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并发指南8:AQS中的公平锁与非公平锁,Condtion
一行一行源码分析清楚 AbstractQueuedSynchronizer (二) 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer ...
- git clone速度太慢解决方案
原文地址:https://blog.csdn.net/hzwwpgmwy/article/details/79043251 适用各种操作系统,本次测试于ubuntu,下载速度从二十几k提高到二百多k ...
- mongoose 建立schema 和model
在node中使用MongoDB很多情况下,都是使用mongoose的,所以这集来介绍一下 安装 yarn add mongoose 连接 const mongoose = require(" ...
- oracle OPEN FOR [USING] 语句
目的: 和ref cursor配合使用, 可以将游标变量分配给不同的SQL (而不是在declare中把游标给定死), 增加处理游标的灵活性语法: declare type type_c ...
- WINFORM控件tabcontrol,隐藏,调用等等
1先说显示项的控制, 第一个是selectedIndex属性这个实用性不是太强,但是如果不涉及到隐藏,删除,增加tabpage的话,也可以用. 第二个是selectedTab=tabPage1,这个属 ...
- LayerDrawable
层图形对象,包含一个Drawable数组,然后按照数组对应的顺序来绘制他们,索引 值最大的Drawable会被绘制在最上层!虽然这些Drawable会有交叉或者重叠的区域,但 他们位于不同的层,所以并 ...
- ELK的安全解决方案 X-Pack(1)
安装 X-Pack 前必须安装 elasticsearch. Kibana.logstash,因为之前安装ELK选择的版本都是5.4.1,所以这次选择X-Pack的版本也要是5.4.1的 第一步:下载 ...
- DB2的web可视化客户端工具
DB2 是IBM公司的产品,目前在银行等金融行业还在大量使用, DB2的客户端工具太,并且难用,这是一直为人所垢病的, 现在TreeSoft数据库管理系统已支持DB2了,直接在浏览器中就可以操作查看 ...
- 配置zabbix监控windows,cmd运行报错cannot connect to Service Manager: [0x00000005]
错误原因: cmd运行没有管理员权限 解决: 找到cmd.exe的位置C:\Windows\System32,选中--右键--使用管理员身份运行 再通过cmd进入到zabbix_agentd文件夹进行 ...
- 《精通并发与Netty》学习笔记(11 - 详解NIO (二) 分散/聚集 Scatter/Gather、Selector)
一.分散/聚集 Scatter/Gather scatter/gather指的在多个缓冲区上实现一个简单的I/O操作,比如从通道中读取数据到多个缓冲区,或从多个缓冲区中写入数据到通道:scatter( ...