Spring多线程环境下Bean的管理策略

举报
隔壁老汪 发表于 2022/06/24 01:12:09 2022/06/24
【摘要】 一、Bean的状态:stateful 与 stateless 有状态会话bean:每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”; 一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。      &n...

一、Bean的状态:stateful 与 stateless


有状态会话bean:每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;

一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的bean。   
    
  无状态会话bean:bean一旦实例化就被加进会话池中,各个用户都可以共用。即使用户已经消亡,bean的生命期也不一定结束,

它可能依然存在于会话池中,供其他用户调用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。

但无状态会话bean并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响。

二、Spring Bean的作用域及状态

1.默认情况下,从Spring bean工厂所取得的实例为singleton(scope属性为singleton),容器只存在一个共享的bean实例。 

2.虽然在Spring容器中controller中会注入service,service中会注入dao,但service与dao中只要不声明私有成员变量,也都是无状态单例的,

所以最终controller中也不声明私有的成员变量,就也是无状态单例的,在多线程环境下依然是安全的

  3.Struts2中的Action因为声明有私有的实例对象或变量,是有状态信息的,在多线程环境下是不安全的,

所以Struts2的Action默认的实现是Prototype模式,scope要配成prototype作用域。 

Prototype: 每次对bean的请求都会创建一个新的bean实例

由上可总结得出:无状态的Bean适合用不变模式,就是单例模式,这样可以共享实例,提高性能。

有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。

三、多线程环境下Bean的处理策略:

1.对于实体bean一般通过方法参数的的形式传递, 参数是局部变量,多线程之间不会有影响。如Spring的DI.

2.对于有状态的bean直接使用prototype原型模式来进行解决。

3.私有成员变量可以用ThreadLocal加以保护,让它们也成为线程安全的状态,这样有状态的Bean就可以在多线程中共享了

如,Hibernate中的sessionFactory,就使用的是 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean,

而在 AnnotationSessionFactoryBean的父类LocalSessionFactoryBean中,定义了大量的ThreadLocal来保证多线程的安全性。 

四、Spring Bean的生命周期:

  1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

      2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

      3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,

           一般称它们的实现类为“后处理器”。

     4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等           非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

五、Spring 多线程环境下对bean的注入

      基于线程安全性,spring不能为多线程注入bean,使用@Resource或者@Autowired注入全部为NULL。

       解决办法:               

                      1.将需要的Bean作为线程的的构造函数的参数传入

                      2.使用ApplicationContext.getBean方法来静态的获取Bean

 

文章来源: blog.csdn.net,作者:隔壁老瓦,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/wxb880114/article/details/88836002

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。