目錄
1. 註解說明
@PostConstruct,@PreDestroy是Java規範JSR-250引入的註解,定義了對象的創建和銷燬工作,同一期規範中還有註解@Resource,Spring也支持了這些註解;
在Spring中,@PostConstruct,@PreDestroy註解的解析是通過BeanPostProcessor實現的,具體的解析類是org.springframework.context.annotation.CommonAnnotationBeanPostProcessor,其父類是org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor,Spring官方說明了該類對JSR-250中@PostConstruct,@PreDestroy,@Resource註解的支持:
Spring's
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
supports the JSR-250javax.annotation.PostConstruct
andjavax.annotation.PreDestroy
annotations out of the box, as init annotation and destroy annotation, respectively. Furthermore, it also supports thejavax.annotation.Resource
annotation for annotation-driven injection of named beans.
2. 調用過程
具體過程是,先IOC容器先解析各個組件的定義信息,解析到@PostConstruct,@PreDestroy的時候,定義爲生命週期相關的方法,組裝組件的定義信息等待初始化;在創建組件時,創建組件並且屬性賦值完成之後,在執行各類初始化方法之前,從容器中找出所有BeanPostProcessor的實現類,其中包括InitDestroyAnnotationBeanPostProcessor,執行所有BeanPostProcessor的postProcessBeforeInitialization方法,在InitDestroyAnnotationBeanPostProcessor中就是找出被@PostConstruct修飾的方法的定義信息,並執行被@PostConstruct標記的方法;
3. 調用分析
@PostConstruct的調用鏈如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(String, Object, RootBeanDefinition)初始化流程中,先執行org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)方法,然後再執行初始化方法:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 在執行初始化方法之前:先執行org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//執行InitializingBean的初始化方法和init-method指定的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)的說明如下:
Apply this BeanPostProcessor to the given new bean instance before any bean initialization callbacks (like InitializingBean's
afterPropertiesSet
or a custom init-method). The bean will already be populated with property values. The returned bean instance may be a wrapper around the original.
調用時機: 在組件創建完屬性複製完成之後,調用組件初始化方法之前;
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(Object, String)的具體流程如下:
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//遍歷所有BeanPostProcessor的實現類,執行BeanPostProcessor的postProcessBeforeInitialization
//在InitDestroyAnnotationBeanPostProcessor中的實現是找出@PostConstruct標記的方法的定義信息,並執行
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
@PreDestroy調用鏈如下:
@PreDestroy是通過org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object, String)被調用(InitDestroyAnnotationBeanPostProcessor實現了該接口),該方法的說明如下:
Apply this BeanPostProcessor to the given bean instance before its destruction. Can invoke custom destruction callbacks.
Like DisposableBean's
destroy
and a custom destroy method, this callback just applies to singleton beans in the factory (including inner beans).
調用時機: 該方法在組件的銷燬之前調用;
org.springframework.beans.factory.support.DisposableBeanAdapter.destroy()的執行流程如下:
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
//調用所有DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((DisposableBean) bean).destroy();
return null;
}
}, acc);
}
else {
//調用DisposableBean的銷燬方法
((DisposableBean) bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
//調用自定義的銷燬方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod();
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
所以是先調用DestructionAwareBeanPostProcessor的postProcessBeforeDestruction(@PreDestroy標記的方法被調用),再是DisposableBean的destory方法,最後是自定義銷燬方法;