Spring生命週期-InitializingBean,DisposableBean

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的銷燬方法,然後再調用自定義的銷燬方法;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章