??@PostConstruct
的应用以及与afterPropertiesSet
、init-method
对比请查看《Spring 注解面面通 之 @PostConstruct 应用解析以及与afterPropertiesSet、init-method对比》。
??@PostConstruct
与InitializingBean
的源码流程有一部分是重叠的,可以参考《Spring 知识面面通 之 InitializingBean 深入源码解析》。
??Spring利用BeanPostProcessor
后置处理器来处理@PostConstruct
和@PreDestroy
注解,InitDestroyAnnotationBeanPostProcessor
是处理@PostConstruct
和@PreDestroy
注解的主要参与者。
??源码解析
??1) AbstractAutowireCapableBeanFactory
的initializeBean(...)
方法。
??① 若Bean
实现了Aware
接口,则触发方法调用。包括:BeanNameAware
、BeanClassLoaderAware
和BeanFactoryAware
。
??② 调用注册的BeanPostProcessor
的postProcessBeforeInitialization(...)
方法。其中InitDestroyAnnotationBeanPostProcessor
用来处理@PostConstruct
和@PreDestroy
注解。
??③ 调用初始化方法,包括InitializingBean
的afterPropertiesSet()
方法和Bean
的init-method
指定的方法。
??④ 调用注册的BeanPostProcessor
的postProcessAfterInitialization(...)
方法。
/*** 初始化给定的Bean实例,应用工厂回调、init方法和Bean后处理程序.* 对于传统定义的Bean,从createBean调用,对于现有的Bean实例从initializeBean调用.* @param beanName 工厂中的Bean名称(用于调试).* @param bean 需要初始化新的Bean实例.* @param mbd 创建Bean时使用的Bean定义(如果给定现有的Bean实例,也可以是null).* @return 初始化的Bean实例(可能被包装).*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 若Bean实现了Aware接口,则触发方法调用.if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {
invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;// 在Bean初始化前处理BeanPostProcessor.// !mbd.isSynthetic()表示用户自定义而非框架所有.if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// 进行Bean初始化,包括如下两种方式:// 1.调用InitializingBean.afterPropertiesSet()方法.// 2.调用Bean配置的init-method方法.try {
invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}// 在Bean初始化后处理BeanPostProcessor.// !mbd.isSynthetic()表示用户自定义而非框架所有.if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
??2) InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(...)
方法。
??① 获取指定Bean
类型生命周期元数据。
??② 调用Bean
类型生命周期元数据的初始化方法。
/*** 初始化之前处理程序.*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 获取Bean类型生命周期元数据.LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());try {
// 调用元数据的初始化方法.metadata.invokeInitMethods(bean, beanName);}catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());}catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);}return bean;
}
??3) InitDestroyAnnotationBeanPostProcessor.invokeInitMethods(...)
方法。
??① 遍历搜集到Bean
的所有初始化方法。
??② 进行Bean
实际初始化方法调用。
/*** 调用元数据的初始化方法.*/
public void invokeInitMethods(Object target, String beanName) throws Throwable {
Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;Collection<LifecycleElement> initMethodsToIterate =(checkedInitMethods != null ? checkedInitMethods : this.initMethods);if (!initMethodsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();for (LifecycleElement element : initMethodsToIterate) {
if (debug) {
logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());}// 调用实际方法.element.invoke(target);}}
}
??4) InitDestroyAnnotationBeanPostProcessor.findLifecycleMetadata(...)
方法。
??① lifecycleMetadataCache
生命周期元数据缓存为空,则重新创建生命周期元数据。
??② 采用双重检查锁机制来进行快速检查,尽量减少对锁的使用。
??③ 若需新建生命周期元数据,调用buildLifecycleMetadata(...)
创建生命周期元数据。
/*** 查找指定类型的生命周期元数据.*/
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
// lifecycleMetadataCache为空,则重新创建生命周期元数据.if (this.lifecycleMetadataCache == null) {
return buildLifecycleMetadata(clazz);}// 首先进行快速检查,只需最少的锁竞争.LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);if (metadata == null) {
metadata = buildLifecycleMetadata(clazz);this.lifecycleMetadataCache.put(clazz, metadata);}return metadata;}}return metadata;
}
??5) InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata(...)
方法。
??① 创建初始化和销毁方法存储集合。
??② 查找initAnnotationType
类型注释的方法,放入初始化方法集合。
??③ 查找destroyAnnotationType
类型注释的方法,放入初始化方法集合。
/*** 创建生命周期元数据.*/
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
final boolean debug = logger.isDebugEnabled();// 初始化方法集合.LinkedList<LifecycleElement> initMethods = new LinkedList<>();// 销毁方法集合.LinkedList<LifecycleElement> destroyMethods = new LinkedList<>();Class<?> targetClass = clazz;do {
// 当前循环初始化方法集合.final LinkedList<LifecycleElement> currInitMethods = new LinkedList<>();// 当前循环销毁方法集合.final LinkedList<LifecycleElement> currDestroyMethods = new LinkedList<>();ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 查找initAnnotationType类型注释的方法.if (initAnnotationType != null && method.isAnnotationPresent(initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);currInitMethods.add(element);if (debug) {
logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);}}// 查找destroyAnnotationType类型注释的方法.if (destroyAnnotationType != null && method.isAnnotationPresent(destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));if (debug) {
logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);}}});// 合并数据.initMethods.addAll(0, currInitMethods);destroyMethods.addAll(currDestroyMethods);targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
??6) CommonAnnotationBeanPostProcessor.CommonAnnotationBeanPostProcessor()
方法。
??① 设置@PostConstruct
注解类型,便于后续搜索@PostConstruct
注释的方法。
??② 设置@PreDestroy
注解类型,便于后续搜索@PreDestroy
注释的方法。
/*** 创建CommonAnnotationBeanPostProcessor,* 初始化和销毁注解类型设置为javax.annotation.PostConstruct和javax.annotation.PreDestroy.*/
public CommonAnnotationBeanPostProcessor() {
// 设置序号.setOrder(Ordered.LOWEST_PRECEDENCE - 3);// 设置@PostConstruct注解类型.setInitAnnotationType(PostConstruct.class);// 设置@PreDestroy注解类型.setDestroyAnnotationType(PreDestroy.class);ignoreResourceType("javax.xml.ws.WebServiceContext");
}
??InitDestroyAnnotationBeanPostProcessor.setInitAnnotationType(...)
和InitDestroyAnnotationBeanPostProcessor.setDestroyAnnotationType(...)
方法。
??① setInitAnnotationType(...)
指定要检查的初始化注解,指示Bean配置后要调用的初始化方法。由于没有必需的注解属性,可以使用任何自定义注解。一般情况下,使用JSR-250
规范提供的javax.annotation.PostConstruct
。
??② setDestroyAnnotationType
指定要检查的销毁注解,指示上下文关闭时要调用的销毁方法。由于没有必需的注解属性,可以使用任何自定义注解。一般情况下,使用JSR-250
规范提供的javax.annotation.PreDestroy
。
/*** 指定要检查的初始化注解,指示Bean配置后要调用的初始化方法.* 可以使用任何自定义注解,因为没有必需的注解属性.* 一般情况下,使用JSR-250规范提供的javax.annotation.PostConstruct.*/
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
this.initAnnotationType = initAnnotationType;
}/*** 指定要检查的销毁注解,指示上下文关闭时要调用的销毁方法.* 可以使用任何自定义注解,因为没有必需的注解属性.* 一般情况下,使用JSR-250规范提供的javax.annotation.PreDestroy.*/
public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
this.destroyAnnotationType = destroyAnnotationType;
}
??总结
??查看源码可以深入了解其实现逻辑,避免应用过程中出现差异。
??源码解析基于spring-framework-5.0.5.RELEASE
版本源码。
??若文中存在错误和不足,欢迎指正!