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的销毁方法,然后再调用自定义的销毁方法;