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 ...
随机推荐
- arcpy.UpdateCursor和arcpy.da.UpdateCursor计算面积时间的比较
arcpy.UpdateCursor ####################### import arcpy from arcpy import env import os import sys f ...
- Uncaught TypeError: l.push is not a function
layui.use([ 'jquery', 'layer', 'element' ], function() {} 而不是 layui.use( 'jquery', 'layer', 'element ...
- 网络时间协议 (SNTP)
sntp是简单网络时间协议(Simple Network Protocol)的客户端,可以用来查询或修正NTP服务器的时间和本地的时差. sntp可以以非交互模式运行或运行一个计划任务的脚本. snt ...
- 高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可能。
小结: 1.内存优化1.一个消息一定只有一块内存使用 Job 聚合消息,Comet 指针引用. 2.一个用户的内存尽量放到栈上内存创建在对应的用户 Goroutine(Go 程)中. 3.内存由自己控 ...
- Spring事务管理3----声明式事务管理(1)
声明式事务管理(1)基于 基于 tx/aop 这种事务管理相比编程式事务管理来说对业务层基本没有改动,通过 TransactionProxyFactoryBean 创建业务层的代理,通过A ...
- java+上传大文件
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 先说下要求: PC端全平台支持,要求支持Windows,Mac,Linux 支持所 ...
- python图论包networks(最短路,最小生成树带包)
官方文档: https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.html 最短路和最小生成树: im ...
- Reveal v4(8796) 使用
文件下载地址 http://xclient.info/s/reveal.html dmg安装成功后, pod install 植入项目. pod 'Reveal-SDK', '~> 4', ...
- RabbitMQ简单Java示例——生产者和消费者
添加Maven依赖: 使用rabbitmq-client的最新Maven坐标: <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp ...
- Visual Studio Code 调试 SpringBoot
Build Anything with Spring Boot:Spring Boot is the starting point for building all Spring-based appl ...