Spring在Thread中注入Bean无效的解决方式
在Spring项目中,有时需要新开线程完成一些复杂任务,而线程中可能需要注入一些服务。而通过Spring注入来管理和使用服务是较为合理的方式。但是若直接在Thread子类中通过注解方式注入Bean是无效的。
因为Spring本身默认Bean为单例模式构建,同时是非线程安全的,因此禁止了在Thread子类中的注入行为,因此在Thread中直接注入的bean是null的,会发生空指针错误。
以下分别列举错误的注入方法和两种解决方式。
错误的注入方法
@Controller
public class SomeController{
@ResponseBody
@RequestMapping("test")
String testInjection(){
// 直接创建并运行线程
new SomeThread().start();
}
}
// 直接编写线程
public SomeThread extends Thread {
@Autowired
SomeService someService;
@Override
public void run(){
// do something...
someService.doSomething();
// 此时 someService实例是null.
}
}
报NullpointException。
通过封装Thread子类注入
个人比较推荐这种方法,对外部代码的影响较小。
@Controller
public class SomeController{
// 通过注解注入封装线程的Bean
@AutoWired
SomeThread someThread;
@ResponseBody
@RequestMapping("test")
String testInjection(){
// 通过注入的Bean启动线程
someThread.execute();
}
}
@Component
public class SomeThread {
// 封装Bean中注入服务
@AutoWired
SomeService someService
public void execute() {
new Worker().start();
}
// 线程内部类,Thread或者Runnable均可
private class Worker extends Thread {
@Override
public void run() {
// do something...
SomeThread.this.someService.doSomething();
// 此时someService已被注入,非null.
}
}
}
正常调用someService。
通过外部引入
即在可以注入的地方先得到可用的实例,在通过Thread子类的构造函数引入。这样会使得在进行代码修改时,影响到每个使用Thread子类的代码,修改工作量大。
@Controller
public class SomeController{
// 通过注解注入Service
@AutoWired
SomeService someService;
@ResponseBody
@RequestMapping("test")
String testInjection(){
// 通过构造函数从外部引入
new Worker(someService).start();
}
}
public class SomeThread {
private SomeService someService;
public SomeThread(SomeService someService){
// 通过构造函数从外部引入
this.someService = someService;
}
@Override
public void run() {
// do something...
someService.doSomething();
// 此时someService非null.
}
}
Spring在Thread中注入Bean无效的解决方式的更多相关文章
- spring给容器中注入组件的几种方式
目录 环境搭建 spring给容器中注入组件 1.包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)适用于把自己写的类加入组件(默认ID类名 ...
- Spring IOC容器中注入bean
一.基于schema格式的注入 1.基本的注入方式 (属性注入方式) 根据setXxx()方法进行依赖注入,Spring只会检查是否有setter方法,是否有对应的属性不做要求 <bean id ...
- Spring在代码中获取bean的几种方式(转:http://www.dexcoder.com/selfly/article/326)
方法一:在初始化时保存ApplicationContext对象 方法二:通过Spring提供的utils类获取ApplicationContext对象 方法三:继承自抽象类ApplicationObj ...
- Spring为IOC容器注入Bean的五种方式
一 @Import导入组件,id默认是组件的全类名 //类中组件统一设置.满足当前条件,这个类中配置的所有bean注册才能生效: @Conditional({WindowsCondition.clas ...
- Spring在代码中获取bean的几种方式
方法一:在初始化时保存ApplicationContext对象 方法二:通过Spring提供的utils类获取ApplicationContext对象 方法三:继承自抽象类ApplicationObj ...
- Spring在代码中获取bean的几种方式(转)
获取spring中bean的方式总结: 方法一:在初始化时保存ApplicationContext对象 ApplicationContext ac = new FileSystemXmlApplica ...
- spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property
spring 在容器中一个bean依赖另一个bean 需要通过ref方式注入进去 通过构造器 或property
- spring 注入bean的两种方式
我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...
- Spring的DI(Ioc) - 注入bean 和 基本数据类型
注入bean有两种方式: 注入其他bean: 方式一 <bean id="orderDao" class="cn.itcast.service.OrderDaoBe ...
随机推荐
- Java实现单例的5种方式
1. 什么是单例模式 单例模式指的是在应用整个生命周期内只能存在一个实例.单例模式是一种被广泛使用的设计模式.他有很多好处,能够避免实例对象的重复创建,减少创建实例的系统开销,节省内存. 2. 单例模 ...
- 01-背包---P2663 越越的组队
P2663 越越的组队 题解 是这题数据水还是...(数据怎么知道我人数有没有超一半啊) 简化题目: 把n个数分成两组,使得较小的一组在不超过n个数总和一半的情况下和最大 (较小的一组之和肯定不超过总 ...
- HttpServletRequest&HttpServletResponse对象
HttpServletRequest&HttpServletResponse对象不是由我们来创建的,而是由tomcat服务器创建,那么我们就可以直接来使用这两个 对象 A: HttpServl ...
- github上有对应官方的各种模型
https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo ...
- 用SSMS连接Azure Sql Database 与连接本地库的一些操作区别
背景 我们知道Azure Sql Database 可以降低运维成本.是一种Pass模式,有资源弹性设置,可以自由调整资源自动对应不同业务高峰(当然也可以降低费用成本),也方便项目后期的资源扩展,以及 ...
- 简单范例php调用C# WebService
准备工作:1. 安装IIS对于PHP的支持,看这里2. 要调用Web Service需要nusoap支持,只要弄个nusoap.php就可以了,把它放在要运行的php文件能够引用的地方,比如我放在同一 ...
- 为什么要设置 Mysql 的 ft_min_word_len=1
为什么要设置 Mysql 的 ft_min_word_len=1 ? 从 Mysql 4.0 开始就支持全文索引功能,但是 Mysql 默认的最小索引长度是 4.如果是英文默认值是比较合理的,但是中文 ...
- 《剑指offer》递推与循环,栈和队列,回溯 (牛客10.27)
难度 题目 知识点 07. 斐波那契数列 递推递归 - 两变量写法- 08. 跳台阶 同上 09. 变态跳台阶 dp 10. 矩形覆盖 同上 05. 用两个栈实现队列 模拟 ☆ 20. 包含min函数 ...
- 【miscellaneous】使用Google语音识别引擎(Google Speech API)[3月5日修改]
原文:http://blog.csdn.net/dlangu0393/article/details/7214728#comments 近期重写本文,暂时禁止评论. 最近在使用Qt编写一个客户端程序的 ...
- 【ARM-LInux开发】如何运行wayland
Running Wayland 原文:https://jan.newmarch.name/Wayland/RunningWayland/ skip table of contents Show tab ...