聊聊InitDestroyAnnotationBeanPostP
序
本文主要研究一下InitDestroyAnnotationBeanPostProcessor
DestructionAwareBeanPostProcessor
spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
/**
* Apply this BeanPostProcessor to the given bean instance before its
* destruction, e.g. invoking custom destruction callbacks.
* <p>Like DisposableBean's {@code destroy} and a custom destroy method, this
* callback will only apply to beans which the container fully manages the
* lifecycle for. This is usually the case for singletons and scoped beans.
* @param bean the bean instance to be destroyed
* @param beanName the name of the bean
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.DisposableBean#destroy()
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#setDestroyMethodName(String)
*/
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
/**
* Determine whether the given bean instance requires destruction by this
* post-processor.
* <p>The default implementation returns {@code true}. If a pre-5 implementation
* of {@code DestructionAwareBeanPostProcessor} does not provide a concrete
* implementation of this method, Spring silently assumes {@code true} as well.
* @param bean the bean instance to check
* @return {@code true} if {@link #postProcessBeforeDestruction} is supposed to
* be called for this bean instance eventually, or {@code false} if not needed
* @since 4.3
*/
default boolean requiresDestruction(Object bean) {
return true;
}
}
DestructionAwareBeanPostProcessor继承了BeanPostProcessor方法,它定义了postProcessBeforeDestruction、requiresDestruction两个方法
InitDestroyAnnotationBeanPostProcessor
spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
@Nullable
private Class<? extends Annotation> initAnnotationType;
@Nullable
private Class<? extends Annotation> destroyAnnotationType;
private int order = Ordered.LOWEST_PRECEDENCE;
@Override
public int getOrder() {
return this.order;
}
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
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;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
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);
}
}
@Override
public boolean requiresDestruction(Object bean) {
return findLifecycleMetadata(bean.getClass()).hasDestroyMethods();
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction...
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
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;
}
}
InitDestroyAnnotationBeanPostProcessor实现了BeanPostProcessor接口定义的postProcessBeforeInitialization方法,DestructionAwareBeanPostProcessor接口的postProcessBeforeInitialization、requiresDestruction方法;其中postProcessBeforeInitialization方法先通过findLifecycleMetadata找到LifecycleMetadata,然后执行invokeInitMethods方法;postProcessBeforeDestruction方法也是先通过findLifecycleMetadata找到LifecycleMetadata,然后执行invokeDestroyMethods方法
LifecycleMetadata
private class LifecycleMetadata {
private final Class<?> targetClass;
private final Collection<LifecycleElement> initMethods;
private final Collection<LifecycleElement> destroyMethods;
@Nullable
private volatile Set<LifecycleElement> checkedInitMethods;
@Nullable
private volatile Set<LifecycleElement> checkedDestroyMethods;
public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods,
Collection<LifecycleElement> destroyMethods) {
this.targetClass = targetClass;
this.initMethods = initMethods;
this.destroyMethods = destroyMethods;
}
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<>(this.initMethods.size());
for (LifecycleElement element : this.initMethods) {
String methodIdentifier = element.getIdentifier();
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
checkedInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<>(this.destroyMethods.size());
for (LifecycleElement element : this.destroyMethods) {
String methodIdentifier = element.getIdentifier();
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
checkedDestroyMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedInitMethods = checkedInitMethods;
this.checkedDestroyMethods = checkedDestroyMethods;
}
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()) {
for (LifecycleElement element : initMethodsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
}
element.invoke(target);
}
}
}
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
Collection<LifecycleElement> destroyMethodsToUse =
(checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
if (!destroyMethodsToUse.isEmpty()) {
for (LifecycleElement element : destroyMethodsToUse) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
}
element.invoke(target);
}
}
}
public boolean hasDestroyMethods() {
Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
Collection<LifecycleElement> destroyMethodsToUse =
(checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
return !destroyMethodsToUse.isEmpty();
}
}
LifecycleMetadata的invokeInitMethods遍历checkedInitMethods通过反射执行init方法,invokeDestroyMethods则是遍历checkedDestroyMethods通过反射执行destroy方法
CommonAnnotationBeanPostProcessor
spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
//......
}
CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,其构造器设置了initAnnotationType为PostConstruct.class,设置destroyAnnotationType为PreDestroy.class
小结
InitDestroyAnnotationBeanPostProcessor实现了BeanPostProcessor接口定义的postProcessBeforeInitialization方法,DestructionAwareBeanPostProcessor接口的postProcessBeforeInitialization、requiresDestruction方法;其中postProcessBeforeInitialization方法先通过findLifecycleMetadata找到LifecycleMetadata,然后执行invokeInitMethods方法;postProcessBeforeDestruction方法也是先通过findLifecycleMetadata找到LifecycleMetadata,然后执行invokeDestroyMethods方法。