Bean作用域和生产周期已经Bean的线程安全问题

bean 的作用域

  • 单例(Singletion) : Spring 容器中只有一个 bean ,这个 bean 在整个应用程序内共享。

  • 原话(Prototype) : 每次 getBean(), 都是不同的bean,都会创建一个实例。

  • 请求(Request):每个HTTP请求都会创建一个新的 Bean 实例。

  • 会话(Session) :每个用户会话会创建一个新的 Bean.

  • 应用程序(Application) : 每个应用程序会创建一个新的 Bean

  • 自定义作用域 @Scope(value = "目标的作用域" , proxyMode = ScopeProxyMode.TARGET.CLASS)

Bean 的生命周期

三分恶面渣逆袭:Bean生命周期四个阶段

对应的完整步骤:

三分恶面渣逆袭:Spring Bean生命周期

实例化

首先通过 createBeanInstanse 创建实例对象,这里使用反射机制利用 BeanClass 拿到类的构造方法,如果有多个构造方法,就拿有@Autowired 注解的构造方法,如果有两个有@Autowired 注解的构造方法,那么就会报错。

选择好构造方法后,就要确定参数,这里会在体内的单例池内进行查找,如果找到了,那么通过反射就可以开始实例化对象了。如果没有找到,那么会报错,信息不完整。

如果选择的是无参构造方法,那么直接构造。

属性填充

通过三级缓存进行依赖注入。

初始化

利用 initializeBean 方法进行初始化

具体步骤

  • 填充初始化容器相关信息

    通过 invokeAwareMethods 方法,为实现 aware 接口(信息感知接口)的Bean 注入 beanName,beanFactory 等容器信息。

  • 初始化构造方法 invokeInitMethods

    通过重写 InitializingBean 接口而实现 afterPropertiesSet 方法来实现的。afterPropertiesSet 写在填充属性后。如果自定义了 initMethod 方法,还会执行这些自定义构造方法。

  • Bean 的后置处理

    在 invokeInitMethods 前后进行

    • applyBeanPostProcessorsBeforeInitialization

    • invokeInitMethods

    • applyBeanPostProcessorsAfterInitialization

使用

将产生的对象放入单例池中。

销毁

在销毁前需要要执行销毁前处理器,这样就会执行 @PreDestroy注解的方法。

然后通过 destroyBeans 方法逐一摧毁体内所有 bean

然后还会执行用户自定义的销毁方法,但是需要手动指定。

单例 Bean 的线程安全问题

单例 Bean 是线程不安全的,如果只对 bean 执行查询的操作,不对bean 进行修改,那么这个单例 Bean 是线程安全的。

解决办法
  • 将单例 bean 定义为多例 Prototype,不方便管理。

  • 在 Bean 对象中,尽量避免定义可变的成员变量,但是这样会限制很多,所以不能这样做。

  • 利用 ThreadLocal,将 Bean 中的成员变量保存在 ThreadLocal 中。

    ThreadLocal 可以保证变量在多线程环境下,保证变量隔离。

    public class MyClass {
        private ThreadLocal<String> threadLocal = new ThreadLocal<>();
    ​
        public void setThreadLocal(String value) {
            threadLocal.set(value);
        }
    ​
        public String getThreadLocal() {
            return threadLocal.get();
        }
    }

    可以在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 里,这是推荐的一种方式。

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值