如果支持JSR-250
,就会添加CommonAnnotationBeanPostProcessor
到 Spring容器。 JSR-250
规范依赖于JSR-175
,因此也是基于Java SE 5.0。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 略。。。
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 略。。。
}
CommonAnnotationBeanPostProcessor
的构造器
// CommonAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
// 设置 InitAnnotationType 为 PostConstruct 注解类
setInitAnnotationType(PostConstruct.class);
// 设置 DestroyAnnotationType 为 PreDestroy 注解类
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
CommonAnnotationBeanPostProcessor
调用父类InitDestroyAnnotationBeanPostProcessor#setInitAnnotationType
方法
// InitDestroyAnnotationBeanPostProcessor
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
this.initAnnotationType = initAnnotationType;
}
因为InitDestroyAnnotationBeanPostProcessor
实现DestructionAwareBeanPostProcessor
接口,也是一个BeanPostProcessor
,所以会在容器初始化时,调用其BeanPostProcessor#postProcessBeforeInitialization
方法
并且会销毁对象时调用DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
方法
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 找到 LifecycleMetadata,LifecycleMetadata 对象有 PostConstruct 注解的方法和 PreDestroy 注解的方法
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 这里也就是执行 @PostConstruct 注解的方法
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;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 这里也就是执行 @PreDestroy 注解的方法
metadata.invokeDestroyMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// 如果缓存不存在,直接创建LifecycleMetadata
return buildLifecycleMetadata(clazz);
}
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
// 用了DCL,从缓存里获取LifecycleMetadata
// 如果不存在,则创建LifecycleMetadata,并放入缓存
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;
}
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
List<LifecycleElement> initMethods = new ArrayList<>();
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
// 不断向上找父类,找 PostConstruct 注解的方法和 PreDestroy 注解的方法
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
// 如果方法上有 PostConstruct 注解,创建 LifecycleElement 对象
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
// 如果方法上有 PreDestroy 注解,创建 LifecycleElement 对象
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
// 添加到 initMethods 集合
initMethods.addAll(0, currInitMethods);
// 添加到 destroyMethods 集合
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 返回LifecycleMetadata对象
return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
@PostConstruct
方法:
- 方法必须没有任何参数,除非是拦截器,在这种情况下,它接受interceptors规范定义的InvocationContext对象
- 非拦截器的方法,不能有返回值
- 除了应用程序客户端之外,该方法不能是静态的
- 方法可以是 final 的
综上所述,Constructor
、@Autowired
、@PostConstruct
这三者的执行顺序是:Constructor
> @Autowired
> @PostConstruct
欢迎小伙伴们积极指正和讨论,一起共同成长。