Spring Bean 生命周期
简单来说,Spring Bean的生命周期可以分为四个大的阶段:实例化 (Instantiation) -> 属性赋值 (Population) -> 初始化 (Initialization) -> 销毁 (Destruction)。
下面我将详细拆解每个步骤,并提供一个流程图帮助你更好地理解。
核心生命周期流程图
flowchart TD A[开始创建Bean] --> B[实例化 Instantiation] B --> C[属性赋值 Population] C --> D[初始化 Initialization] D --> E[投入使用] E --> F[销毁 Destruction] subgraph B [实例化] B1[推断构造函数] B2[执行构造函数 new] end subgraph C [属性赋值] C1[依赖注入 DI] C2[处理 Aware 接口] end subgraph D [初始化] D1[BeanPostProcessor.postProcessBeforeInitialization] D2[@PostConstruct] D3[InitializingBean.afterPropertiesSet] D4[自定义 init-method] D5[BeanPostProcessor.postProcessAfterInitialization
AOP在此发生] end B1 --> B2 B2 --> C1 C1 --> C2 C2 --> D1 D1 --> D2 D2 --> D3 D3 --> D4 D4 --> D5 D5 --> E subgraph F [销毁容器] F1[@PreDestroy] F2[DisposableBean.destroy] F3[自定义 destroy-method] end
详细步骤解析
第一阶段:实例化 (Instantiation)
- 加载Bean定义:Spring容器启动时,会读取配置文件(如XML)或扫描注解(如
@Component
),将Bean的定义信息(BeanDefinition)加载到容器中。 - 推断构造函数:根据BeanDefinition中的信息,决定使用哪个构造函数来创建Bean实例(无参?有参?)。
- 执行构造函数:通过反射(Reflection)调用选中的构造函数,仅仅是为对象分配内存空间,生成一个“原始”的对象。此时对象的属性都是默认值(如null, 0),依赖还没有被注入。
注意:如果使用了
@Configuration
和@Bean
,方法体的执行也在这一步。
第二阶段:属性赋值/填充 (Population)
- 依赖注入 (DI):Spring解析对象之间的依赖关系,并将所需的依赖(其他Bean、配置值等)通过反射注入到对象的属性中(例如,通过
@Autowired
,@Value
或XML中的<property>
标签)。 - 处理Aware接口:如果Bean实现了各种
Aware
接口(如BeanNameAware
,BeanFactoryAware
,ApplicationContextAware
),Spring会回调相应的方法,将容器本身的一些组件(如Bean的名字、工厂、上下文)注入给Bean。
第三阶段:初始化 (Initialization)
这是步骤最繁杂的阶段,也是扩展点最多的阶段。
6. BeanPostProcessor前置处理:所有实现了BeanPostProcessor
接口的类,会执行其postProcessBeforeInitialization()
方法。这是Spring提供的一个强大的扩展点,允许你在初始化开始前对Bean进行修改。
7. 执行@PostConstruct
方法:执行被@PostConstruct
注解标记的方法。这是JSR-250规范提供的注解。
8. 执行InitializingBean
接口:如果Bean实现了InitializingBean
接口,会执行其afterPropertiesSet()
方法。
9. 执行自定义初始化方法:执行在BeanDefinition中指定的自定义初始化方法(例如XML中init-method
属性或@Bean(initMethod = "...")
指定的方法)。
10. BeanPostProcessor后置处理:所有BeanPostProcessor
会再次执行其postProcessAfterInitialization()
方法。这是Spring AOP(面向切面编程)创建代理对象的关键时机! 如果Bean需要被增强(例如事务管理@Transactional
),Spring会在这里为其创建一个代理对象并返回。之后容器中和开发者使用的,其实是这个代理对象,而不是原始的目标对象。
初始化顺序:
BeanPostProcessor.before
->@PostConstruct
->InitializingBean
->init-method
->BeanPostProcessor.after
经过以上所有步骤,Bean已经完全创建好,会被放入Singleton Bean缓存池中,等待被使用。
第四阶段:销毁 (Destruction)
当Spring容器被关闭时(例如调用applicationContext.close()
),会对容器中的单例Bean进行销毁。
11. 执行@PreDestroy
方法:执行被@PreDestroy
注解标记的方法。这也是JSR-250规范提供的。
12. 执行DisposableBean
接口:如果Bean实现了DisposableBean
接口,会执行其destroy()
方法。
13. 执行自定义销毁方法:执行在BeanDefinition中指定的自定义销毁方法(例如XML中destroy-method
属性或@Bean(destroyMethod = "...")
指定的方法)。
销毁顺序:
@PreDestroy
->DisposableBean
->destroy-method
总结与记忆技巧
- 大阶段:记住 创建(实例化 -> 填充 -> 初始化) -> 使用 -> 销毁。
- 扩展点:重点关注几个重要的扩展接口和注解:
- 影响所有Bean:
BeanPostProcessor
(非常强大,但通常由框架实现) - 针对单个Bean:
- 初始化:
@PostConstruct
(推荐) >InitializingBean
>init-method
- 销毁:
@PreDestroy
(推荐) >DisposableBean
>destroy-method
- 初始化:
- 获取容器信息:
Aware
系列接口。
- 影响所有Bean: