Spring项目bean 无法注入问题--Thread中注入Bean无效

版权声明:summer https://blog.csdn.net/yk614294861/article/details/84103577

有时候在spring项目中可能会遇到依赖的属性没有被注入,这个时候可能有很多原因。spring默认是单例的,通常注入的时候我们使用比较多的是@Autowired,这个注解默认按照类型注入(同时会处理依赖关系)。

当没有注入的时候,即使用的时候值为null ,会报空指针异常 ,需要查看此属性的bean 有没有被spring初始化并管理,比如bean有没有被扫描到,或者配置。

今天这这里我研究的是另一种情况,Thread中注入Bean

在Spring项目中,有时需要新开线程完成一些复杂任务,而线程中可能需要注入一些服务(例如此新开的线程需要将得到的数据写入数据库等)。而通过Spring注入来管理和使用服务是较为合理的方式。但是若直接在Thread子类中通过注解方式注入Bean是无效的。@Resource或者@Autowired注入全部为NULL,

因为Spring本身默认Bean为单例模式构建,同时是非线程安全的,因此禁止了在Thread子类中的注入行为,因此在Thread中直接注入的bean是null的,会发生空指针错误。

错误代码X------这里的ywBuildingService 是不能被注入的

@Service
public class GuanLinSyncQueue implements Runnable {

	private Logger logger = Logger.getLogger(GuanLinSyncQueue.class);

	private static final String qianchuanCommunityCode = Global.getConfig("qianchuanCommunityCode");

	@Autowired
	private YwBuildingService ywBuildingService;

	@PostConstruct
	public void init() {
		Thread thread = new Thread(new GuanLinSyncQueue());
		thread.start();
	}

	@Override
	public void run() {
            ywBuildingService.save(ywBuildingPojo)
	}
}

对于此有如下两种解决方法:

  1. 将需要的Bean作为线程的的构造函数的参数传入
  2. 将线程类作为服务类的内部类,Thread或者Runnable均可

方案1:

对于第一种方法,需要将要用到的bean 全部当作线程类的属性,如果bean数量少,也比较方便。注意这个线程类中引入了 ywBuildingService 这个属性。并且在GuanLinSyncQueue 这个可以被spring 管理的bean中注入 ywBuildingService 并通过构造函数 将ywBuildingService 传给了MyThread

public class MyThread implements Runnable {
	private Logger logger = Logger.getLogger(GuanLinSyncQueue.class);
	
	private static final String qianchuanCommunityCode = Global.getConfig("qianchuanCommunityCode");

	private YwBuildingService ywBuildingService;
	
	
//构造方法 传入spring 容易 中的 ywBuildingService  
	public MyThread(YwBuildingService ywBuildingService) {
		super();
		this.ywBuildingService = ywBuildingService;
	}

	@Override
	public void run() {
		ywBuildingService.save(ywBuildingPojo)
	}
}



------------------------------------------分割线--------------------------------


@Service
public class GuanLinSyncQueue{	

	private Logger logger = Logger.getLogger(GuanLinSyncQueue.class);

	private static final String qianchuanCommunityCode = Global.getConfig("qianchuanCommunityCode");

	@Autowired
	private YwBuildingService ywBuildingService;

	@PostConstruct
	public void init() {

		Thread thread = new Thread(new MyThread(ywBuildingService));
		thread.start();		
		
	}
}
	

方案2:推荐方案!!!将线程类作为服务类的内部类,可以方便直接使用外部类中注入的bean.

@Service
public class GuanLinSyncQueue{	

	private Logger logger = Logger.getLogger(GuanLinSyncQueue.class);

	private static final String qianchuanCommunityCode = Global.getConfig("qianchuanCommunityCode");

	@Autowired
	private YwBuildingService ywBuildingService;

	@PostConstruct
	public void init() {		
		new worker().start();
	}
	
	private class worker extends Thread{
		@Override
		public void run() {
            //做自己想做的事情
			ywBuildingService.save(ywBuildingPojo);
		}
	}
	

}

猜你喜欢

转载自blog.csdn.net/yk614294861/article/details/84103577
今日推荐