七、Spring Bean 的生命周期

七、Spring Bean 的生命周期

Spring Bean 的生命周期是从Bean的实例化之后(通过反射创建出对象之后),到Bean成为一个完整的对象,最终存储到单例池之中,这个过程被称为Bean的生命周期。Spring Bean的生命周期大致分为三个阶段:

  • Bean实例化阶段:
    • Spring框架会取出BeanDefinition信息进行判断当前Bean的范围是否是singleton,是否延迟记载…最终将singleton的Bean通过反射实例化;
  • Bean初始化阶段:
    • Bean创建之后(是个半成品),还要对其属性进行填充,执行一些Aware接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法,执行自定义init方法等。涉及到Aop增强,Spring注解,Bean循环引用等问题。
  • Bean的完成阶段:
    • 初始化后的Bean是一个完整的Spring Bean,存储在singletonObjects,这就完成了整个生命周期。

7.1 Bean初始化阶段

涉及到以下几个阶段:

  • Bean实例的属性填充;
  • Aware接口属性注入;
  • BeanPostProcessor的before()方法回调;
  • InitializingBean接口的初始化方法回调;
  • 自定义初始化方法回调;
  • BeanPostProcessor的after()方法回调;

7.1.1 Bean实例的属性填充

BeanDefinition中对当前Bean实体的注入信息通过属性propertyValues进行存储;

Spring 进行属性填充时,有以下几种情况:

  • 对String,int等基本属性注入,直接通过set方法的反射设置;
  • 对单向对象引用属性注入,从容器中getBean的方式获取后set方法反射设置;如果容器中没有,则先创建被注入对象的实例(整个生命周期后,及属性注入等操作完成),再注入;
  • 双向对象属性的引用,会涉及到循环依赖循环引用)的问题;

循环依赖:多个实体间相互依赖并形成闭环的情况;如BeanA依赖于BeanB,BeanB依赖于BeanA。

public class DUserServiceImpl implements DUserService {
    public void setUserDao(DUserDao userDao) { }
}

public class DUserDaoImpl implements DUserDao {
    public void setUserService(DUserService userService) { }
}
<bean id="dUserService" class="xxx.DUserServiceImpl">
        <property name="userDao" ref="dUserDao"></property>
</bean>

<bean id="dUserDao" class="xxx.DUserDaoImpl">
        <property name="userService" ref="dUserServce"></property>
</bean>

在这里插入图片描述

解决循环依赖的方案:三级缓存

Spring 提供三级缓存存储完整的Bean和半成品的Bean,用来解决循环依赖。

在DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry中的方法:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	// 最终存储单例完整Bean的容器,这里的Bean实例化和初始化都完成,称为  一级缓存
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    // 早期Bean单例池,缓存半成品的Bean,且当前对象被其他对象引用,称为  二级缓存
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
    // 单例Bean的工厂池,缓存半成品的Bean,当前对象未被引用,使用时通过工厂创建Bean,称为  三级缓存
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
}

UserService和UserDao循环依赖结合三级缓存的过程:

  • UserService实例化对象,尚未初始化,将实例化后的UserService存储到三级缓存;
  • UserService属性注入,需要引用UserDao,从缓存中获取,没有UserDao;需要实例化UserDao;
  • UserDao实例化对象尚未初始化,将实例化后的UserDao存储到三级缓存;
  • UserDao属性注入,需要引用UserService,从三级缓存中获取,有UserService;UserService从三级缓存移到二级缓存;
  • UserDao继续执行其他生命周期过程,最终成为一个完成的Bean,存到一级缓存,删除二三级缓存;
  • UserService注入UserDao;
  • UserService继续执行其他生命周期过程,最终成为一个完成的Bean,存到一级缓存,删除二三级缓存;

图解如下:

在这里插入图片描述

7.2 Spring IOC 基本流程

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值