CommonAnnotationBeanPostProcessor间接实现了BeanPostProcessor接口,属于Spring中的一个扩展,主要用于处理 @PostConstruct@PreDestroy@Resource 等常用注解。其关系如下图。

Spring之CommonAnnotationBeanPostProcessor_后置处理器

一、案例准备

1、配置类

package com.example.demo.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan("com.example.demo")
@Configuration
public class AppConfiguration {
}

2、实体类

package com.example.demo.entity;

import java.io.Serializable;

@Data
public class User implements Serializable {

    private Long id;

    private String name;

    private Integer age;
}

3、业务逻辑类

package com.example.demo.service.impl;

import com.example.demo.service.MenuService;
import com.example.demo.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

@Service
public class MenuServiceImpl implements MenuService {

    @Resource
    private RoleService roleService;

    @PostConstruct
    public void testPostConstruct() {
       System.out.println("== PostConstruct ==");
    }

    @PreDestroy
    public void testPreDestroy() {
       System.out.println("== PreDestroy ==");
    }

    @Override
    public void print() {
       System.out.println("MenuServiceImpl");
    }
}

--------------------------------------------------------------
    
package com.example.demo.service.impl;

import com.example.demo.service.RoleService;
import org.springframework.stereotype.Service;

@Service
public class RoleServiceImpl implements RoleService {
	@Override
	public void print() {
		System.out.println("RoleServiceImpl");
	}
}

4、测试类

package com.example.demo.main;

import com.example.demo.config.AppConfiguration;
import com.example.demo.service.impl.UserServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTest {
    public static void main(String[] args) {
       AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
       applicationContext.register(AppConfiguration.class);
       applicationContext.refresh();

       MenuServiceImpl menuService = applicationContext.getBean(MenuServiceImpl.class);
       menuService.print();
       // 这里需要显式调用一下,用于测试 @PreDestroy 注解的方法调用
       applicationContext.close();
    }
}

二、源码解析(基于Spring-5.3.32版本)

1、关键处理方法

(1)org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
	把加了 @Resource 注解的属性和方法,以及加了 @PostConstruct 和 @PreDestroy 的方法全部找出并缓存。
  
(2)org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties
	对加了 @Resource 注解的属性和方法进行处理,若为属性则反射注入,若为方法则反射调用。
  
(3)org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
	初始化前执行加了 @PostConstruct 注解的方法
  
(4)org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
	销毁前执行加了 @PreDestroy 注解的方法

2、源码分析

(1)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

从 applyMergedBeanDefinitionPostProcessors 方法开始,该方法会将加了 @Resource 注解的属性和方法,以及加了 @PostConstruct 和 @PreDestroy 的方法全部找出并缓存。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
       throws BeanCreationException {

    ......省略
    ......省略
    ......省略

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
       if (!mbd.postProcessed) {
          try {
             // 循环后置处理器,并调用各自的实现
             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
          }
          catch (Throwable ex) {
             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                   "Post-processing of merged bean definition failed", ex);
          }
          mbd.postProcessed = true;
       }
    }

    ......省略
    ......省略
    ......省略
}


protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        // processor 为 CommonAnnotationBeanPostProcessor,断点进入调试
        // 将加了 @PostConstruct、@PreDestroy、@Resource 注解的方法全部找出并缓存
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}
(2)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition(查找并缓存@Resource、@PostConstruct、@PreDestroy)
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 查找加了 @PostConstruct 和 @PreDestroy 的方法并缓存
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    // 查找加了 @Resource 的属性和方法并缓存
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    // 校验查找结果
    metadata.checkConfigMembers(beanDefinition);
}

// 下面文章会分别根据上面三段代码进行分析,考虑到阅读体验,只保留关键代码,所以想知道细节的还是要自己花时间调试。

postProcessMergedBeanDefinition

// 主要看 buildLifecycleMetadata 方法

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    LifecycleMetadata metadata = findLifecycleMetadata(beanType);
    metadata.checkConfigMembers(beanDefinition);
}

----------------------------------------------------------------------------
    
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) {
                // 找出结果并封装到 LifecycleMetadata 中
                metadata = buildLifecycleMetadata(clazz);
                this.lifecycleMetadataCache.put(clazz, metadata);
            }
            return metadata;
        }
    }
    return metadata;
}

----------------------------------------------------------------------------
    
// 重点
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
        return this.emptyLifecycleMetadata;
    }

    List<LifecycleElement> initMethods = new ArrayList<>();
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<LifecycleElement> currInitMethods = new ArrayList<>();
        final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

        // 对实例化对象中的方法进行处理
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 找出所有加了 @PostConstruct 的方法
            if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
                if (logger.isTraceEnabled()) {
                    logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
                }
            }
            // 找出所有加了 @PreDestroy 的方法
            if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
                if (logger.isTraceEnabled()) {
                    logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
                }
            }
        });

        // 分别放入集合当中
        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        // 处理父类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    // 将结果放入到 LifecycleMetadata 实例中
    return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
            new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

----------------------------------------------------------------------------

// 下面两个方法主要让你知道 this.injectedElements 是在这里赋值的
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
    // 加了注解后 elements 一般不为空
    return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
            new InjectionMetadata(clazz, elements));
}

public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
    this.targetClass = targetClass;
    // 关键点
    this.injectedElements = elements;
}

至于 this.initAnnotationType 和 this.destroyAnnotationType 的赋值操作,则是在实例化 CommonAnnotationBeanPostProcessor 时做的。如下代码。

// CommonAnnotationBeanPostProcessor 构造器

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    // 给 this.initAnnotationType 赋值
    setInitAnnotationType(PostConstruct.class);
    // 给 this.destroyAnnotationType 赋值
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");

    // java.naming module present on JDK 9+?
    if (jndiPresent) {
       this.jndiFactory = new SimpleJndiBeanFactory();
    }
}

public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
	this.initAnnotationType = initAnnotationType;
}

public void setDestroyAnnotationType(Class<? extends Annotation> destroyAnnotationType) {
	this.destroyAnnotationType = destroyAnnotationType;
}

findResourceMetadata

private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
    // Fall back to class name as cache key, for backwards compatibility with custom callers.
    String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
    // Quick check on the concurrent map first, with minimal locking.
    InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
       synchronized (this.injectionMetadataCache) {
          metadata = this.injectionMetadataCache.get(cacheKey);
          if (InjectionMetadata.needsRefresh(metadata, clazz)) {
             if (metadata != null) {
                metadata.clear(pvs);
             }
             // 构建 Resource 元数据
             metadata = buildResourceMetadata(clazz);
             this.injectionMetadataCache.put(cacheKey, metadata);
          }
       }
    }
    return metadata;
}

----------------------------------------------------------------------------

// 下面这段代码有点长,但其实很简单
private InjectionMetadata buildResourceMetadata(Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
        return InjectionMetadata.EMPTY;
    }

    List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        // 处理属性
        // 找出加了 @WebServiceRef @EJB @Resource 等注解的属性,并存放到 currElements 中
        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                }
                currElements.add(new WebServiceRefElement(field, field, null));
            }
            else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@EJB annotation is not supported on static fields");
                }
                currElements.add(new EjbRefElement(field, field, null));
            }
            else if (field.isAnnotationPresent(Resource.class)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@Resource annotation is not supported on static fields");
                }
                if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                    currElements.add(new ResourceElement(field, field, null));
                }
            }
        });

        // 处理方法
        // 找出加了 @WebServiceRef @EJB @Resource 等注解的方法,并存放到 currElements 中
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
            if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                return;
            }
            if (webServiceRefClass != null && bridgedMethod.isAnnotationPresent(webServiceRefClass)) {
                if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@WebServiceRef annotation is not supported on static methods");
                    }
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new WebServiceRefElement(method, bridgedMethod, pd));
                }
            }
            else if (ejbClass != null && bridgedMethod.isAnnotationPresent(ejbClass)) {
                if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@EJB annotation is not supported on static methods");
                    }
                    if (method.getParameterCount() != 1) {
                        throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
                    }
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new EjbRefElement(method, bridgedMethod, pd));
                }
            }
            // 常用的一个注解 @Resource
            else if (bridgedMethod.isAnnotationPresent(Resource.class)) {
                if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    // @Resource不支持静态方法
                    if (Modifier.isStatic(method.getModifiers())) {
                        throw new IllegalStateException("@Resource annotation is not supported on static methods");
                    }
                    Class<?>[] paramTypes = method.getParameterTypes();
                    // @Resource作用的方法只能有一个参数
                    if (paramTypes.length != 1) {
                        throw new IllegalStateException("@Resource annotation requires a single-arg method: " + method);
                    }
                    if (!this.ignoredResourceTypes.contains(paramTypes[0].getName())) {
                        PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                        currElements.add(new ResourceElement(method, bridgedMethod, pd));
                    }
                }
            }
        });

        elements.addAll(0, currElements);
        // 处理父类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

----------------------------------------------------------------------------

// 为了方便阅读,这段复制了一份
// 下面两个方法主要让你知道 this.injectedElements 是在这里赋值的
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
    // 加了注解后 elements 一般不为空
    return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
            new InjectionMetadata(clazz, elements));
}

public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
    this.targetClass = targetClass;
    // 关键点
    this.injectedElements = elements;
}

checkConfigMembers

public void checkConfigMembers(RootBeanDefinition beanDefinition) {
    // this.injectedElements 取值看上面
    Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
    for (InjectedElement element : this.injectedElements) {
       Member member = element.getMember();
       // 去除重复值
       if (!beanDefinition.isExternallyManagedConfigMember(member)) {
          beanDefinition.registerExternallyManagedConfigMember(member);
          checkedElements.add(element);
       }
    }
    // 最终结果
    this.checkedElements = checkedElements;
}

小结:加了 @Resource 的属性和方法会缓存到 this.injectedElements 中,加了 @PostConstruct 注解的方法会缓存到 this.initMethods,加了 @PreDestroy 注解的方法会缓存到 this.destroyMethods。(this.checkedElements 变量在 org.springframework.beans.factory.annotation.InjectionMetadata 中;this.checkedInitMethodsthis.checkedDestroyMethods 变量在 org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata 中。

(3)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(处理@Resource)
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ......省略
    ......省略
    ......省略
        
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
       if (pvs == null) {
          pvs = mbd.getPropertyValues();
       }
       for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
          // CommonAnnotationBeanPostProcessor 对 @Resource 注解进行处理
          PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
             if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
             }
             pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
             if (pvsToUse == null) {
                return;
             }
          }
          pvs = pvsToUse;
       }
    }
    ......省略
    ......省略
    ......省略
}

----------------------------------------------------------------------------
    
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 从缓存中取出加了 @Resource 注解的属性和方法的元数据
    InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
    try {
        // 通过反射处理。若为属性则反射注入,若为方法则反射调用
        metadata.inject(bean, beanName, pvs);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
    }
    return pvs;
}

----------------------------------------------------------------------------
    
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    // 从缓存取数据
    Collection<InjectedElement> checkedElements = this.checkedElements;
    Collection<InjectedElement> elementsToIterate =
        (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        for (InjectedElement element : elementsToIterate) {
            // 循环反射处理
            element.inject(target, beanName, pvs);
        }
    }
}

----------------------------------------------------------------------------
// 到这一步就很清晰明了了
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
				throws Throwable {
	// 判断是否为属性
    if (this.isField) {
        Field field = (Field) this.member;
        ReflectionUtils.makeAccessible(field);
        // 通过反射为属性赋值
        field.set(target, getResourceToInject(target, requestingBeanName));
    }
    else {
        if (checkPropertySkipping(pvs)) {
            return;
        }
        try {
            Method method = (Method) this.member;
            ReflectionUtils.makeAccessible(method);
            // java 中的方法反射
            method.invoke(target, getResourceToInject(target, requestingBeanName));
        }
        catch (InvocationTargetException ex) {
            throw ex.getTargetException();
        }
    }
}
(4)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(处理@PostConstruct)
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    ......省略
    ......省略
    ......省略

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
       // 初始化之前执行后置处理器的方法
       wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    ......省略
    ......省略
    ......省略

    return wrappedBean;
}

----------------------------------------------------------------------------
    
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 循环后置处理器,在初始化之前执行相应后置处理器的方法
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

----------------------------------------------------------------------------
    
// @PostConstruct 和 @PreDestroy 的处理都在 InitDestroyAnnotationBeanPostProcessor 中
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 从缓存中取出加了 @PostConstruct 注解的方法元数据
    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;
}

----------------------------------------------------------------------------
    
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());
            }
            // 反射调用 @PostConstruct 注解方法
            element.invoke(target);
        }
    }
}

// 这一步就很明了,java中的方法反射
public void invoke(Object target) throws Throwable {
    ReflectionUtils.makeAccessible(this.method);
    this.method.invoke(target, (Object[]) null);
}
(5)org.springframework.beans.factory.support.DisposableBeanAdapter#destroy(处理@PreDestroy)
@Override
public void destroy() {
    if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
       for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
          // 后置处理器方法调用
          processor.postProcessBeforeDestruction(this.bean, this.beanName);
       }
    }

    ......省略
    ......省略
    ......省略
}

----------------------------------------------------------------------------

// InitDestroyAnnotationBeanPostProcessor 中的方法 postProcessBeforeDestruction
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    // 获取缓存中加了 @PreDestroy 注解的方法元数据
    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);
    }
}

----------------------------------------------------------------------------

public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
    // 加了 @PreDestroy 注解的方法的缓存
    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());
            }
            // 反射调用加了 @PreDestroy 注解的方法
            element.invoke(target);
        }
    }
}

// java中的方法反射
public void invoke(Object target) throws Throwable {
    ReflectionUtils.makeAccessible(this.method);
    this.method.invoke(target, (Object[]) null);
}


Spring之CommonAnnotationBeanPostProcessor_后置处理器_02