Spring生命週期註解之@PostConstruct,@PreDestroy

目錄

1. 註解說明

2. 調用過程

3. 調用分析


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-250 javax.annotation.PostConstruct and javax.annotation.PreDestroy annotations out of the box, as init annotation and destroy annotation, respectively. Furthermore, it also supports the javax.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方法,最後是自定義銷燬方法;

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