Spring Bean 生命周期:注册、初始化、注入及后置操作执行顺序
Spring Bean 生命周期:注册、初始化、注入及后置操作执行顺序
Spring Bean 的生命周期包含多个阶段,了解这些阶段的执行顺序对于正确使用 Spring 框架至关重要。以下是完整的执行顺序:
1. Bean 定义注册阶段
- 配置源读取:Spring 读取 XML、Java Config 或组件扫描的配置
- BeanDefinition 注册:将 Bean 定义注册到
BeanDefinitionRegistry
- 对于
@Component
扫描的类:通过ClassPathBeanDefinitionScanner
- 对于 Java Config:通过
@Bean
方法 - 对于 XML:通过
BeanDefinitionParser
- 对于
2. Bean 实例化阶段(容器启动时)
- 依赖排序:Spring 解析 Bean 之间的依赖关系,确定创建顺序
- 实例化 Bean:
- 通过构造函数或工厂方法创建 Bean 实例
- 此时 Bean 属性还未注入,是"半成品"
3. 依赖注入阶段
- 属性注入:
@Autowired
字段注入@Autowired
setter 方法注入@Value
值注入
- Aware 接口回调(按顺序):
BeanNameAware.setBeanName()
BeanClassLoaderAware.setBeanClassLoader()
BeanFactoryAware.setBeanFactory()
EnvironmentAware.setEnvironment()
EmbeddedValueResolverAware.setEmbeddedValueResolver()
ResourceLoaderAware.setResourceLoader()
(仅适用于应用上下文)ApplicationEventPublisherAware.setApplicationEventPublisher()
(仅适用于应用上下文)MessageSourceAware.setMessageSource()
(仅适用于应用上下文)ApplicationContextAware.setApplicationContext()
4. 初始化阶段
@PostConstruct
注解方法InitializingBean.afterPropertiesSet()
接口实现- 自定义 init 方法(XML 中
init-method
或@Bean(initMethod = "init")
)
5. 后置处理器阶段
BeanPostProcessor.postProcessBeforeInitialization()
在所有初始化回调之前BeanPostProcessor.postProcessAfterInitialization()
在所有初始化回调之后
6. 使用阶段
- Bean 完全初始化,可供其他 Bean 使用
7. 销毁阶段(容器关闭时)
@PreDestroy
注解方法DisposableBean.destroy()
接口实现- 自定义 destroy 方法(XML 中
destroy-method
或@Bean(destroyMethod = "cleanup")
)
完整执行顺序图示
Bean定义注册 → 实例化 → 依赖注入 →
│
├─ Aware接口回调 →
│
├─ BeanPostProcessor.postProcessBeforeInitialization() →
│
├─ 初始化阶段:
│ ├─ @PostConstruct →
│ ├─ InitializingBean.afterPropertiesSet() →
│ └─ 自定义init方法 →
│
├─ BeanPostProcessor.postProcessAfterInitialization() →
│
└─ 使用阶段 → 销毁阶段
关键注解和接口的执行顺序
- 构造器或
@Bean
工厂方法 @Autowired
和@Value
注入Aware
接口回调@PostConstruct
InitializingBean.afterPropertiesSet()
- 自定义 init 方法
@PreDestroy
DisposableBean.destroy()
- 自定义 destroy 方法
示例代码
@Component
public class ExampleBean implements BeanNameAware, InitializingBean, DisposableBean {@Autowiredprivate Dependency dependency;@Value("${some.property}")private String someProperty;public ExampleBean() {System.out.println("1. Constructor");}@Autowiredpublic void setAnotherDependency(AnotherDependency dep) {System.out.println("2. @Autowired setter");}@Overridepublic void setBeanName(String name) {System.out.println("3. BeanNameAware: " + name);}@PostConstructpublic void postConstruct() {System.out.println("4. @PostConstruct");}@Overridepublic void afterPropertiesSet() {System.out.println("5. InitializingBean.afterPropertiesSet()");}public void customInit() {System.out.println("6. Custom init method");}@PreDestroypublic void preDestroy() {System.out.println("7. @PreDestroy");}@Overridepublic void destroy() {System.out.println("8. DisposableBean.destroy()");}public void customDestroy() {System.out.println("9. Custom destroy method");}
}
特殊场景说明
-
循环依赖:Spring 通过三级缓存解决构造器注入的循环依赖问题
- 一级缓存:单例对象池
- 二级缓存:早期暴露的原始对象
- 三级缓存:对象工厂
-
代理对象:AOP 代理会在依赖注入完成后创建,可能影响某些生命周期回调的顺序
-
懒加载:
@Lazy
Bean 会在第一次被请求时初始化,而不是容器启动时
理解 Spring Bean 生命周期的完整顺序有助于解决复杂的依赖问题,正确使用各种回调方法,以及在适当的时候执行初始化逻辑。