很多刚学 Spring 的朋友,一看到 Bean 生命周期直接头大,又是实例化又是初始化,一堆名词堆在一起,感觉特别绕。其实没那么玄乎,你就把 Bean 理解成 Spring 帮你 new 出来、管理的对象就行,从出生到最后销毁,就是它完整的生命周期。
Bean 的生命周期大体上有四大步: 实例化阶段 → 初始化阶段(属性填充 / Aware / before / InitializingBean / init / after)→ 完成阶段存入单例池
一、Bean 实例化的基本流程
Spring 容器在进行初始化时,会将 xml 配置的的信息封装成一个 BeanDefinition 对象,所有的 BeanDefinition 存储到一个名为 beanDefinitionMap 的 Map 集合中去,Spring 框架在对该 Map 进行遍历,使用反射创建 Bean 实例对象,创建好的 Bean 对象存储在一个名为 singletonObjects 的 Map 集合中,当调用 getBean 方法时则最终从该 Map 集合中取出 Bean 实例对象返回
1.1 Bean 信息定义对象 - BeanDefinition

Bean 信息定义对象 - BeanDefinition
BeanDefinition 存储到一个名为 beanDefinitionMap
对象存储在一个名为 singletonObjects 的 Map
1.2 基本流程四步
- 加载 xml 配置文件,解析获取配置中的每个的信息,封装成一个个的
BeanDefinition对象; - 将
BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中; ApplicationContext底层遍历beanDefinitionMap,创建 Bean 实例对象;- 创建好的 Bean 实例对象,被存储到一个名为
singletonObjects的Map<String,Object>中;
二、Spring 的后处理器
Spring 的后处理器是 Spring 对外开发的重要扩展点,允许我们介入到 Bean 的整个实例化流程中来,以达到动态注册 BeanDefinition,动态修改 BeanDefinition,以及动态修改 Bean 的作用。Spring 主要有两种后处理器:
BeanFactoryPostProcessor:Bean 工厂后处理器,在BeanDefinitionMap填充完毕,Bean 实例化之前执行;BeanPostProcessor:Bean 后处理器,一般在 Bean 实例化之后,填充到单例池singletonObjects之前执行。
2.1 BeanFactoryPostProcessor
Bean 工厂后处理器 -- BeanFactoryPostProcessor
BeanFactoryPostProcessor 是一个接口规范,实现了该接口的类只要交由 Spring 容器管理的话,那么 Spring 就会回调该接口的方法,用于对 BeanDefinition 注册和修改的功能。
演示修改:
- 创建
BeanFactoryPostProcessor实现类并重写方法 - 注入实现类
演示注册:
- 创建
BeanFactoryPostProcessor实现类并重写方法 - 注入实现类
2.2 BeanDefinitionRegistryPostProcessor
Bean 工厂后处理器 -- BeanDefinitionRegistryPostProcessor
Spring 提供了一个 BeanFactoryPostProcessor 的子接口 BeanDefinitionRegistryPostProcessor 专门用于注册 BeanDefinition 操作。
java
public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
BeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName("com.apesource.pojo.Student");
beanDefinitionRegistry.registerBeanDefinition("stu",beanDefinition);
}
}

2.3 BeanPostProcessor
Bean 后处理器 -- BeanPostProcessor
Bean 被实例化后,到最终缓存到名为 singletonObjects 单例池之前,中间会经过 Bean 的初始化过程,例如:属性的填充、初始方法 init 的执行等,其中有一个对外进行扩展的点 BeanPostProcessor,我们称为 Bean 后处理。跟上面的 Bean 工厂后处理器相似,它也是一个接口,实现了该接口并被容器管理的 BeanPostProcessor,会在流程节点上被 Spring 自动调用。
java
//1. 自定义 MyBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {
/* 参数: bean 是当前被实例化的 Bean , beanName 是当前 Bean 实例在容器中的名称
返回值:当前 Bean 实例对象 */
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor 的 before 方法 ...");
return bean;
}
/* 参数: bean 是当前被实例化的 Bean , beanName 是当前 Bean 实例在容器中的名称
返回值:当前 Bean 实例对象 */
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor 的 after 方法 ...");
return bean;
}
}
XML
```xml
//2. 注入配置 MyBeanPostProcessor
<bean class="com.apesource.processors.MyBeanPostProcessor"></bean>
java
//3. 测试控制台打印结果如下
User 创建了...
BeanPostProcessor 的 before 方法...
User 属性填充...
User 初始化方法执行...
BeanPostProcessor 的 after 方法...
com.apesource.pojo.User@56ac3a89

三、Spring Bean 的生命周期
Spring Bean 的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到 Bean 成为一个完整对象,最终存储到单例池中,这个过程被称为 Spring Bean 的生命周期。Spring Bean 的生命周期大体上分为四个阶段:
- Bean 的实例化阶段 :Spring 框架会取出
BeanDefinition的信息进行判断当前 Bean 的范围是否是 singleton 的,是否不是延迟加载的,是否不是 FactoryBean 等,最终将一个普通的 singleton 的 Bean 通过反射进行实例化; - Bean 的属性填充阶段:Bean 创建之后还仅仅是个"半成品",还需要对 Bean 实例的属性进行填充
- Bean 的初始化阶段 :此外还可能执行一些 Aware 接口方法、执行
BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化 init 方法等。该阶段是 Spring 最具技术含量和复杂度的阶段; - Bean 的完成阶段 :经过初始化阶段,Bean 就成为了一个完整的 Spring Bean,被存储到单例池
singletonObjects中去了,即完成了 Spring Bean 的整个生命周期。
由于 Bean 的初始化阶段的步骤比较复杂,所以着重研究 Bean 的初始化阶段。
3.1 Spring Bean 的初始化过程
Spring Bean 的初始化过程涉及如下几个过程:
- Bean 实例的属性填充
- Aware 接口属性注入
BeanPostProcessor的before()方法回调InitializingBean接口的初始化方法回调- 自定义初始化方法 init 回调
BeanPostProcessor的after()方法回调
3.2 Bean 实例属性填充
BeanDefinition 中有对当前 Bean 实体的注入信息通过属性 propertyValues 进行了存储。
总结: Spring 在进行属性注入时,会分为如下几种情况:
- 注入普通属性,String、int 或存储基本类型的集合时,直接通过 set 方法的反射设置进去;
- 注入单向对象引用属性时,从容器中
getBean获取后通过 set 方法反射设置进去,如果容器中没有,则先创建被注入对象 Bean 实例(完成整个生命周期)后,在进行注入操作; - 注入双向对象引用属性时,就比较复杂了,涉及了循环引用(循环依赖)。
3.3 注入单向对象引用属性演示
3.4 注入双向对象引用属性演示
含义:多个实体之间相互依赖并形成闭环的情况就叫做"循环依赖",也叫做"循环引用"。

3.5 常用的 Aware 接口
Aware 接口是一种框架辅助属性注入的一种思想,其他框架中也可以看到类似的接口。框架具备高度封装性,我们接触到的一般都是业务代码,一个底层功能 API 不能轻易的获取到,但是这不意味着永远用不到这些对象,如果用到了,就可以使用框架提供的类似 Aware 的接口,让框架给我们注入该对象。
总结:处理器的作用,为 Bean 生命周期各个阶段提供扩展

| Aware 接口 | 回调方法 | 作用 |
|---|---|---|
ServletContextAware |
setServletContext(ServletContext context) |
Spring 框架回调方法注入 ServletContext 对象,web 环境下才生效 |
BeanFactoryAware |
setBeanFactory(BeanFactory factory) |
Spring 框架回调方法注入 beanFactory 对象 |
BeanNameAware |
setBeanName(String beanName) |
Spring 框架回调方法注入当前 Bean 在容器中的 beanName |
ApplicationContextAware |
setApplicationContext(ApplicationContext applicationContext) |
Spring 框架回调方法注入 applicationContext 对象 |
四、一句话简单总结
其实核心一句话:Bean 生命周期,就是 Spring 从准备创建这个对象,到对象能用,最后程序关闭把对象干掉的全过程。