一、不推荐把“线程”注入到spring

将线程注入到Spring容器中并不是一个常见的做法,而且通常也不推荐这样做,原因如下:

  1. 生命周期管理困难: Spring管理的Bean生命周期由Spring容器管理,而线程的生命周期由JVM管理。将线程注入到Spring容器中会导致线程的生命周期与Spring容器的生命周期绑定,这可能会导致线程的生命周期不受你的控制,难以达到预期的效果。

  2. 线程安全问题: Spring容器本身是线程安全的,但线程对象并不一定是线程安全的。如果将线程注入到Spring容器中,可能会引入线程安全问题,因为Spring容器对线程的管理方式与普通Bean不同。

  3. 可维护性和可读性差: 将线程注入到Spring容器中会增加代码的复杂度,降低代码的可维护性和可读性。开发人员不太容易理解和维护这样的代码。

  4. 不符合设计原则: 将线程注入到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,并在线程中使用,但这种方式应该谨慎使用,并且通常不被推荐,因为它可能会带来一些潜在问题。

  1. 违背依赖注入原则: Spring推荐使用依赖注入来将Bean传递到组件中,而不是通过ApplicationContext直接获取。这种直接获取Bean的方法被称为"Service Locator"模式,这种模式会使代码耦合到Spring容器,从而降低代码的可测试性和灵活性。

  2. 不易于测试: 如果在线程中直接使用ApplicationContext获取Bean,这种代码在测试时需要模拟Spring容器,增加了测试的复杂性。

  3. 增加耦合: 线程直接获取Spring的Bean会使代码与Spring容器紧密耦合,这使得代码难以在不依赖Spring的环境中使用。

如果在某些特殊情况下确实需要在线程中获取Spring管理的Bean,请确保你在应用中正确配置了ApplicationContext,并且保证获取Bean的操作不会影响线程安全性。

在线程中使用Spring的Bean的方法、不推荐把“线程”注入到Spring的更多相关文章

  1. Spring获取bean工具类,可用于在线程里面获取bean

    Spring获取bean工具类,可用于在线程里面获取bean import java.util.Locale; import org.springframework.beans.BeansExcept ...

  2. 普通Java类获取Spring的Bean的方法

    普通Java类获取Spring的Bean的方法 在SSH集成的前提下.某些情况我们需要在Action以外的类中来获得Spring所管理的Service对象. 之前我在网上找了好几好久都没有找到合适的方 ...

  3. 普通java类获取spring容器bean的方法

    很多时候,我们在普通的java类中需要获取spring的bean来做操作,比如,在线程中,我们需要操作数据库,直接通过spring的bean中构建的service就可以完成.无需自己写链接..有时候有 ...

  4. Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效)

    Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效) 前言 今天在使用Spring cache的Cacheable注解的过程中遇见了一个Cacheable注解失效的问题, ...

  5. Spring 中IOC(控制反转)&& 通过SET方式为属性注入值 && Spring表达式

    ### 1. Spring IoC IoC:Inversion of control:控制反转:在传统开发模式下,对象的创建过程和管理过程都是由开发者通过Java程序来实现的,操作权在开发者的Java ...

  6. 使用Spring实例化Bean的方法以及Bean取别名

    一.通过构造方法实例化Bean bean中加构造方法 public class Bean1 { public Bean1() { System.out.println("Bean1构造方法. ...

  7. C#学习之在辅助线程中修改UI控件----invoke方法

    Invoke and BeginInvoke 转载地址:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html 在Invo ...

  8. 老问题:Android子线程中更新UI的3种方法

    在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 方法一:用Handler 1.主线程中定义Handler: Handle ...

  9. 一个解决在非UI线程中访问UI 异常的小方法

    写 WPF 的童鞋可能都会碰到 在非UI线程中访问 UI 异常的问题.这是为了防止数据不一致做的安全限制. 子线程中更新UI还要交给主线程更新,引用满天飞,实在是麻烦. 接下来,我们推出一个可以称之为 ...

  10. Android子线程中更新UI的4种方法

    方法一:用Handler 1.主线程中定义Handler: Handler mHandler = new Handler() { @Override public void handleMessage ...

随机推荐

  1. linux上pip install mysqlclient报错

    linux上pip install mysqlclient报错 django连接mysql数据库时 乱糟糟的 一大片红色报错,查了半天资料,失败了无数次,最终终于成功 先用以下代码: sudo apt ...

  2. 开发必会系列:hibernate事务

    一  事务定义及特性 1.数据库事务的定义:数据库事务(Database Transaction) 是指由一个或多个SQL语句组成的工作单元,这个工作单元中的SQL语句相互依赖,如果有一个SQL语句执 ...

  3. 阿里二面:Java中锁的分类有哪些?你能说全吗?

    引言 在多线程并发编程场景中,锁作为一种至关重要的同步工具,承担着协调多个线程对共享资源访问秩序的任务.其核心作用在于确保在特定时间段内,仅有一个线程能够对资源进行访问或修改操作,从而有效地保护数据的 ...

  4. Springboot Mybatis 全局变量使用

    application.properties中配置 mybatis.configuration.variables.k1='v1' mybatis.configuration.variables.k2 ...

  5. quartus之ram的IP测试

    quartus之ram的IP测试 1.基本原理 ram,读取存储器,用于储存数据.基本的原理就是使用时钟驱动时序,利用地址区分位置,使用使能控制写入.输出的结果以写入的位宽输出. 2.实际操作 顶层代 ...

  6. 使用 MediaStream Recording API 和 Web Audio API 在浏览器中处理音频(未完待续)

    使用 MediaStream Recording API 和 Web Audio API 在浏览器中处理音频 1. 背景 最近项目上有个需求,需要实现:录音.回放录音.实现音频可视化效果.上传wav格 ...

  7. #树上带修莫队,树链剖分#洛谷 4074 [WC2013]糖果公园

    题目 分析 考虑将树转换成序列求解,那就用欧拉序,入栈一次出栈一次正好抵消掉 注意当起点不是LCA的时候要将起点加入,剩下就是带修莫队板子题了 代码 #include <cstdio> # ...

  8. #trie,树链剖分#洛谷 6088 [JSOI2015]字符串树

    题目 分析 显然树上的问题可以转换成根节点到两点的答案减去2倍根节点到LCA的答案 化边为点,考虑子节点承接父节点的trie,再加入一条新的字符串, 在循环的过程中统计一个位置被多少个字符串经过, 这 ...

  9. [AHOI2014/JSOI2014/一本通1722]骑士游戏 题解 (spfa做dp)

    题目描述 在游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击.两种攻击方式都会消耗JYY一些体力.采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个 ...

  10. C# 报错 Lc.exe已退出 代码为-1 如何解决

    完美解决方案:把项目文件夹下Properties文件夹下的licenses.licx文件删除,重新编译即可: