多线程中使用spring容器中的对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程中使用spring容器中的对象相关的知识,希望对你有一定的参考价值。

参考技术A 创建一个自己的类用来实现ApplicationContextAware,然后通过类名或者实例名称来获取spring容器中的实例。

@Component

public class SpringContextUtilsimplements ApplicationContextAware

private static ApplicationContextcontext;

public void setApplicationContext(ApplicationContext applicationContext)throws BeansException

context=applicationContext;



public static T getBeanByClass(Class c)

return context.getBean(c);



public static Object getBeanByName(String name)

return context.getBean(name);





这里一定要有@Component注解,不然还是取不到spring容器里的实例,取到的值是null。

这样就可以在多线程中使用了:

MonitorTrafficService service = SpringContextUtils.getBeanByClass(MonitorTrafficService.class);

Spring框架中的单例bean是线程安全的吗?

1、介绍两个概念

      有状态的bean:对象中有实例变量(成员变量),可以保存数据,是非线程安全的

      无状态的bean:对象中没有实例变量(成员变量),不能保存数据,可以在多线程环境下共享,是线程安全的

2、spring的线程安全问题

      2.1 我们都知道spring中的bean默认都是单例的,ioc容器中一个类只会存在一个实例对象。这种设计是怎么保证线程安全的?

        一般不会出现线程安全问题。在spring中,绝大部分bean都是无状态的,因此即使这些bean默认是单例的,也不会出现线程安全问题的。比如controller、service、dao这些类,这些类里面通常不会含有成员变量,因此它们被设计成单例的。如果这些类中定义了实例变量,就线程不安全了,所以尽量避免定义实例变量。

      2.2 对于spring中有状态的bean,比如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder,为什么也能够设计成单例的呢?它是怎么保证线程安全的?

    对于有状态的bean,spring采用ThreadLocal进行处理,使它们成为线程安全可以共享的对象
    对于有状态的bean,也可以使用原型模式(prototype),每次使用时都会重新生成一个对象,解决了线程不安全的问题
    无状态的Bean适合使用不变模式,即单例模式,这样可以共享实例,提高性能。有状态的Bean,多线程环境下不安全,适合使用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。

以上是关于多线程中使用spring容器中的对象的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架中的单例bean是线程安全的吗?

Java(多)线程中注入Spring的Bean

Spring框架中的容器以及两大特性

扫地阿姨看完都学会了!Spring容器如何解决循环依赖的原理

多线程时Autowired自动注入问题

Spring 中的bean 是线程安全的吗?