IOC容器的組件除通過聲明自定義初始化和銷燬方法外,可以實現InitializingBean接口和DisposableBean接口,在實現內中完成初始化和銷燬的邏輯;
InitializingBean的接口定義如下:
package org.springframework.beans.factory;
public interface InitializingBean {
/**
在組件創建對象並賦值完所有的屬性之後被調用
*/
void afterPropertiesSet() throws Exception;
}
DisposableBean的接口定義如下:
package org.springframework.beans.factory;
public interface DisposableBean {
/**
在容器銷燬組件的時候被調用
*/
void destroy() throws Exception;
}
InitializingBean的調用鏈如下
可以看到,跟自定義的初始化方法一起,在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(String, Object, RootBeanDefinition)中被調用,具體的執行方法如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {
//判斷組件是否實現了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 調用InitializingBean的實現方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 調用自定義初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
可以看到,在執行初始化方法的時候,是先調用InitializingBean的初始化方法,然後再調用自定義的初始化方法;
DisposableBean的調用鏈如下:
也是在跟自定義銷燬方法一起,在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(String, DisposableBean)中被調用,具體執行方法如下:
protected void destroyBean(String beanName, DisposableBean bean) {
// Trigger destruction of dependent beans first...
// 先銷燬依賴的組件
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
// 銷燬組件
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
...
..
.
}
到org.springframework.beans.factory.support.DisposableBeanAdapter.destroy()中
@Override
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
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);
}
}
}
可以看到,在執行初始化方法的時候,是先調用DisposableBean的銷燬方法,然後再調用自定義的銷燬方法;