简介
为了与容器对Bean生命周期的管理进行交互,你可以实现Spring InitializingBean
和 DisposableBean
接口。容器为前者调用 afterPropertiesSet()
,为后者调用 destroy()
JSR-250的
@PostConstruct
和@PreDestroy
注解通常被认为是在现代Spring应用程序中接收生命周期回调的最佳实践。使用这些注解意味着你的Bean不会被耦合到Spring特定的接口。详情请参见 使用 使用@PostConstruct
和@PreDestroy
。如果你不想使用JSR-250注解,但你仍然想消除耦合,可以考虑用
init-method
和destroy-method
bean 定义元数据。
初始化回调
org.springframework.beans.factory.InitializingBean
接口让Bean在容器对Bean设置了所有必要的属性后执行初始化工作。InitializingBean
接口指定了一个方法。
1 | void afterPropertiesSet() throws Exception; |
1 | public class AnotherExampleBean implements InitializingBean { |
建议使用
@PostConstruct
注解或指定一个POJO初始化方法。在基于XML的配置元数据中,你可以使用init-method
属性来指定具有 void 无参数签名的方法的名称。对于Java配置,你可以使用@Bean
的initMethod
属性
销毁回调
实现 org.springframework.beans.factory.DisposableBean
接口可以让Bean在包含它的容器被销毁时获得一个回调。DisposableBean
接口指定了一个方法。
1 | void destroy() throws Exception; |
建议使用
@PreDestroy
注解或指定一个bean定义所支持的通用方法。对于基于XML的配置元数据,你可以使用<bean/>
上的destroy-method
属性。使用Java配置,你可以使用@Bean
的destroyMethod
属性。
1 | public class AnotherExampleBean implements DisposableBean { |
默认的初始化和销毁方法
在spring可以配置全局默认的初始化和销毁方法,不用为每个bean来每次指定初始化和销毁方法。
1 | <beans default-init-method="init" default-destroy-method="destory"> |
结合生命周期机制
从Spring 2.5开始,有三个选项来控制Bean的生命周期行为。
InitializingBean
和DisposableBean
callback 接口。- 自定义
init()
anddestroy()
方法。 @PostConstruct
和@PreDestroy
注解。你可以结合这些机制来控制一个特定的Bean。
如果一个bean设置了多种生命周期回调方法,并且方法名都不相同,则初始化时调用顺序如下:
- 注解了
@PostConstruct
的方法。 afterPropertiesSet()
,如InitializingBean
回调接口所定义。- 一个自定义配置的
init()
方法。
销毁方法的调用顺序是一样的。
- 注解了
@PreDestroy
的方法。 destroy()
,正如DisposableBean
回调接口所定义的那样。- 一个自定义配置的
destroy()
方法。
结合源码
在spring中bean的创建中,在被实例化后,首先会使用 Bean 定义中的属性值填充给定 BeanWrapper 中的 Bean 实例。接下来调用BeanPostProcessor
中的postProcessBeforeInitialization
的方法,@PostConstruct
和@PreDestroy
注解会被CommonAnnotationBeanPostProcessor
执行,所以这两个注解会最先执行,之后会调用invokeInitMethods
方法来调用初始化方法,例:
1 | protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd) |