- 背景
写一个SpringBoot程序,把从接口传过来的数据放进队列,用线程将数据读进数据库和redis。在启动类创建了一个全局队列,通过实现runable接口的方式写了一个线程A,在线程中用@Autowird 注入 service层的对象调用操作数据库的办法。原本打算在启动类通过 new Thread( new A())起一个线程,调试的时候发现线程A中注入的service为null。
2. 出现问题
线程A中注入的service为null,导致数据没有写到数据库和redis。
3. 出现原因
经过请教同事,知道了new 出来的实例不会交给Spring容器管理,所以实例里面的 service或者dao注入不进来。
4. 解决办法
自己写了一个工具类BeanUtils实现不通过new 也能拿到实例,在启动类通过工具管理类getBean拿到实例 起一个线程,解决啦!!!
5.代码
BeanUtils 工具类的代码如下:
package com.ws.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class BeanUtils implements ApplicationContextAware { protected static ApplicationContext applicationContext ; @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { if (applicationContext == null) { applicationContext = arg0; } } public static Object getBean(String name) { //name表示其他要注入的注解name名 return applicationContext.getBean(name); } /** * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象 */ public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }
启动类:
Intersms_userThread intersms_userthread = BeanUtils.getBean(Intersms_userThread.class); // 通过BeanUtils.getBean的方式拿到intersms_userthread的实例,这样就可以在intersms_userthread中使用@Autowired 注入service了 Thread IntersmsSaveThread = new Thread(intersms_userthread); IntersmsSaveThread.start();
6. 待解决
通过上述步骤,@Autowired 注入为null的问题就解决了,下面是我在实践中遇到的问题,后期不断学习回来继续补充:
我尝试在Intersms_userThread.java 这个类里面通过
IntersmsService service = BeanUtils.getBean(IntersmsService .class);
引入service,但是在getBean里面applicationContext为null
标签:applicationContext,service,Autowired,getBean,线程,null,BeanUtils,注入 From: https://www.cnblogs.com/sheep-see/p/17836769.html