常用的設(shè)定方式有以下三種:
通過實現(xiàn) InitializingBean/DisposableBean 接口來定制初始化之后/銷毀之前的操作方法;
通過 @Bean的 initMethod/destroyMethod 屬性指定初始化之后 /銷毀之前調(diào)用的操作方法;
在指定方法上加上@PostConstruct 或@PreDestroy注解來制定該方法是在初始化之后還是銷毀之前調(diào)用。
public class InitSequenceBean implements InitializingBean {
public InitSequenceBean() {
System.out.println("InitSequenceBean: constructor");
}
@PostConstruct
public void postConstruct() {
System.out.println("InitSequenceBean: postConstruct");
}
public void initMethod() {
// 使用@Bean(initMethod="initMethod")聲明
System.out.println("InitSequenceBean: init-method");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitSequenceBean: afterPropertiesSet");
}
}
輸出結(jié)果:
InitSequenceBean: constructor
InitSequenceBean: postConstruct
InitSequenceBean: afterPropertiesSet
InitSequenceBean: init-method
通過上述輸出結(jié)果,說明三種初始化的順序是:
Constructor > @PostConstruct > InitializingBean > init-method
原因:
@PostConstruct注解后的方法在BeanPostProcessor前置處理器中就被執(zhí)行了。我們知道BeanPostProcessor接口是一個回調(diào)的作用,Spring容器的每個受管Bean在調(diào)用初始化方法之前,都會獲得BeanPostProcessor接口實現(xiàn)類的一個回調(diào)。在BeanPostProcessor的方法中有一段邏輯就是會判斷當前被回調(diào)的bean的方法中有沒有被initAnnotationType/destroyAnnotationType注釋,如果有,則添加到init/destroy隊列中,后續(xù)一一執(zhí)行。initAnnotationType/destroyAnnotationType注解就是@PostConstruct/@PreDestroy。所以@PostConstruct當然要先于InitializingBean和init-method執(zhí)行了。
從圖中,我們可以看到實例化Bean的過程中有以下幾個節(jié)點:
1)設(shè)置屬性值;
2)調(diào)用Bean中的BeanNameAware.setBeanName()方法,如果該Bean實現(xiàn)了BeanNameAware接口;
3)調(diào)用Bean中的BeanFactoryAware.setBeanFactory()方法,如果該Bean實現(xiàn)了BeanFactoryAware接口;
4)調(diào)用BeanPostProcessors.postProcessBeforeInitialization()方法;@PostConstruct注解后的方法就是在這里被執(zhí)行的
5)調(diào)用Bean中的afterPropertiesSet方法,如果該Bean實現(xiàn)了InitializingBean接口;
6)調(diào)用Bean中的init-method,通常是在配置bean的時候指定了init-method,例如:<bean class="beanClass" init-method="init"></bean>
7)調(diào)用BeanPostProcessors.postProcessAfterInitialization()方法;
8)如果該Bean是單例的,則當容器銷毀并且該Bean實現(xiàn)了DisposableBean接口的時候,調(diào)用destory方法;如果該Bean是prototype,則將準備好的Bean提交給調(diào)用者,后續(xù)不再管理該Bean的生命周期。


