在线程中使用Spring的Bean的方法、不推荐把“线程”注入到Spring
一、不推荐把“线程”注入到spring
将线程注入到Spring容器中并不是一个常见的做法,而且通常也不推荐这样做,原因如下:
生命周期管理困难: Spring管理的Bean生命周期由Spring容器管理,而线程的生命周期由JVM管理。将线程注入到Spring容器中会导致线程的生命周期与Spring容器的生命周期绑定,这可能会导致线程的生命周期不受你的控制,难以达到预期的效果。
线程安全问题: Spring容器本身是线程安全的,但线程对象并不一定是线程安全的。如果将线程注入到Spring容器中,可能会引入线程安全问题,因为Spring容器对线程的管理方式与普通Bean不同。
可维护性和可读性差: 将线程注入到Spring容器中会增加代码的复杂度,降低代码的可维护性和可读性。开发人员不太容易理解和维护这样的代码。
不符合设计原则: 将线程注入到Spring容器中违反了单一职责原则和依赖倒置原则。线程应该由专门的线程管理类管理,而不应该与Spring容器耦合在一起。
因此,通常建议将需要使用Spring容器管理的Bean注入到线程中,而不是将线程注入到Spring容器中。
二、线程中使用spring的bean的方法
1、通过构造函数注入或Setter方法注入(推荐)
1.1、构造方法注入
如果你需要在线程中使用Spring的Bean,推荐通过依赖注入的方式将Bean传递到线程中。你可以通过构造函数注入或Setter方法注入,将需要的Bean传递给线程实例。这样做不仅符合Spring的依赖注入原则,还可以确保代码更易于测试和维护。
下面是一个通过依赖注入将Spring管理的Bean传递给线程的示例:
public class MyRunnable implements Runnable {
private final MyService myService;
public MyRunnable(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
myService.performTask();
}
}
// 在需要创建线程的地方使用依赖注入
@Autowired
private MyService myService;
public void startThread() {
MyRunnable myRunnable = new MyRunnable(myService);
Thread thread = new Thread(myRunnable);
thread.start();
}
在这个示例中,通过构造函数将MyService注入到线程中,避免了直接从ApplicationContext获取Bean的做法。这样可以保持代码的灵活性、可测试性和可维护性。
1.2、Setter方法注入
当使用Setter方法注入时,需要在线程类中定义一个Setter方法,用于接收需要注入的Bean。以下是一个使用Setter方法注入的示例:
public class MyRunnable implements Runnable {
private MyService myService;
// Setter方法用于注入MyService
public void setMyService(MyService myService) {
this.myService = myService;
}
@Override
public void run() {
if (myService != null) {
myService.performTask();
} else {
throw new IllegalStateException("MyService has not been set.");
}
}
}
// 在需要创建线程的地方进行Setter方法注入
@Autowired
private MyService myService;
public void startThread() {
MyRunnable myRunnable = new MyRunnable();
myRunnable.setMyService(myService); // 使用Setter方法注入MyService
Thread thread = new Thread(myRunnable);
thread.start();
}
在这个示例中,MyRunnable类定义了一个setMyService方法,用于接收MyService实例。在startThread方法中,首先创建了MyRunnable实例,然后通过调用setMyService方法将MyService实例注入到线程中。这样就完成了使用Setter方法进行注入的操作。
2、Spring的getBean获取Bean,然后在线程中使用(不推荐)
可以使用Spring的ApplicationContext来获取Bean,并在线程中使用,但这种方式应该谨慎使用,并且通常不被推荐,因为它可能会带来一些潜在问题。
违背依赖注入原则: Spring推荐使用依赖注入来将Bean传递到组件中,而不是通过
ApplicationContext直接获取。这种直接获取Bean的方法被称为"Service Locator"模式,这种模式会使代码耦合到Spring容器,从而降低代码的可测试性和灵活性。不易于测试: 如果在线程中直接使用
ApplicationContext获取Bean,这种代码在测试时需要模拟Spring容器,增加了测试的复杂性。增加耦合: 线程直接获取Spring的Bean会使代码与Spring容器紧密耦合,这使得代码难以在不依赖Spring的环境中使用。
如果在某些特殊情况下确实需要在线程中获取Spring管理的Bean,请确保你在应用中正确配置了ApplicationContext,并且保证获取Bean的操作不会影响线程安全性。
在线程中使用Spring的Bean的方法、不推荐把“线程”注入到Spring的更多相关文章
- Spring获取bean工具类,可用于在线程里面获取bean
Spring获取bean工具类,可用于在线程里面获取bean import java.util.Locale; import org.springframework.beans.BeansExcept ...
- 普通Java类获取Spring的Bean的方法
普通Java类获取Spring的Bean的方法 在SSH集成的前提下.某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象. 之前我在网上找了好几好久都没有找到合适的方 ...
- 普通java类获取spring容器bean的方法
很多时候,我们在普通的java类中需要获取spring的bean来做操作,比如,在线程中,我们需要操作数据库,直接通过spring的bean中构建的service就可以完成.无需自己写链接..有时候有 ...
- Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效)
Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效) 前言 今天在使用Spring cache的Cacheable注解的过程中遇见了一个Cacheable注解失效的问题, ...
- Spring 中IOC(控制反转)&& 通过SET方式为属性注入值 && Spring表达式
### 1. Spring IoC IoC:Inversion of control:控制反转:在传统开发模式下,对象的创建过程和管理过程都是由开发者通过Java程序来实现的,操作权在开发者的Java ...
- 使用Spring实例化Bean的方法以及Bean取别名
一.通过构造方法实例化Bean bean中加构造方法 public class Bean1 { public Bean1() { System.out.println("Bean1构造方法. ...
- C#学习之在辅助线程中修改UI控件----invoke方法
Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...
- 老问题:Android子线程中更新UI的3种方法
在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 方法一:用Handler 1.主线程中定义Handler: Handle ...
- 一个解决在非UI线程中访问UI 异常的小方法
写 WPF 的童鞋可能都会碰到 在非UI线程中访问 UI 异常的问题.这是为了防止数据不一致做的安全限制. 子线程中更新UI还要交给主线程更新,引用满天飞,实在是麻烦. 接下来,我们推出一个可以称之为 ...
- Android子线程中更新UI的4种方法
方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage ...
随机推荐
- 安全测试系列:《web安全深度剖析》读书笔记
一 基础 1.http请求流程: 请求.响应报文格式: 8种请求方式,get(长度有限制).head(用于测试资源是否存在,服务器不返回消息主体).post(传输大量数据).put(给服务器上传资源) ...
- flutter3-dylive仿抖音App实例|Flutter3+Getx实战短视频直播应用
原创研发flutter3+getX+mediaKit跨平台仿抖音app短视频直播实战Flutter3-DouYin. flutter3_dylive使用最新跨平台技术flutter3.x+dart3+ ...
- 散列表的数据结构以及对象在JVM堆中的存储过程
[版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/129916399 出自[进步* ...
- 2024-03-27:用go语言,多维费用背包。 给你一个二进制字符串数组 strs 和两个整数 m 和 n, 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个
2024-03-27:用go语言,多维费用背包. 给你一个二进制字符串数组 strs 和两个整数 m 和 n, 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 ...
- 【已解决】(MySQL)SQL注入绕过登陆验证直接登陆---用户名输入框注释sql密码语句段
今天学习了一种sql注入方法,通过注释密码验证部分的sql语句. 这是登陆界面 在用户名如果输入 15284206891' and 1=1 # 密码可以随意输入即可登陆成功 原理如下: 在sql可视化 ...
- 手写数字图片识别——DL 入门案例
Deep Learning Demo of Primary 下面介绍一个入门案例,如何使用TensorFlow和Keras构建一个CNN模型进行手写数字识别,以及如何使用该模型对自己的图像进行预测.尽 ...
- #计数#A 古老谜题
From NOIP2020 模拟赛 B 组 Day4 题目 给定一个长度为\(n\)的01序列\(a\), 问有多少个三元组\((l,p,r),1\leq l<p<r\leq n\) 满足 ...
- #状压dp#C 计划带师
分析 状压dp显然,主要是字典序的问题, 考虑初态终态转换就可以保证字典序最小了 代码 #include <cstdio> #include <cctype> #include ...
- C++ 数学函数、头文件及布尔类型详解
C++ 数学 C++ 有许多函数可以让您在数字上执行数学任务. 最大值和最小值 max(x, y) 函数可用于找到 x 和 y 的最大值: 示例 cout << max(5, 10); 而 ...
- Docker学习路线12:开发者体验
到目前为止,我们只讨论了使用Docker来部署应用程序.然而,Docker也是一个极好的用于开发应用程序的工具.可以采用一些不同的建议来改善开发体验. 在应用程序中使用docker-compose以方 ...