spring源码解析bean销毁@PreDestroy

前言

这次主要跟踪下@PreDestroy这个注解的源码过程

正文

找到这个类

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor,@PostConstruct和@PreDestroy都是这个类来具体实现的,本次主要介绍@PreDestroy,初始化的后续介绍。

上篇文章已经介绍过了,在bean销毁之前会执行到这个方法org.springframework.beans.factory.support.DisposableBeanAdapter#destroy

@Override
   public void destroy() {
//    执行beanPostProcessors,beanPostProcessors用对对bean的过程进行处理的抽象
      if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
         for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
//          在bean销毁之前进行一些处理
            processor.postProcessBeforeDestruction(this.bean, this.beanName);
         }
      }

//    如果bean实现了DisposableBean接口
      if (this.invokeDisposableBean) {
         if (logger.isDebugEnabled()) {
            logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");
         }
         try {
            if (System.getSecurityManager() != null) {
               AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                  ((DisposableBean) bean).destroy();
                  return null;
               }, acc);
            }
            else {
//             bean实现DisposableBean接口的方式,注解调用子类destroy方法
               ((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) {
//       执行bean定义中指定的bean销毁方法
         invokeCustomDestroyMethod(this.destroyMethod);
      }
      else if (this.destroyMethodName != null) {
         Method methodToCall = determineDestroyMethod(this.destroyMethodName);
         if (methodToCall != null) {
            invokeCustomDestroyMethod(methodToCall);
         }
      }
   }

找到这行代码

在bean销毁之前进行一些处理
            processor.postProcessBeforeDestruction(this.bean, this.beanName);

找到org.springframework.beans.factory.support.DisposableBeanAdapter#DisposableBeanAdapter()这个方法的这行代码

this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
@Nullable
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
   List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
   if (!CollectionUtils.isEmpty(processors)) {
      filteredPostProcessors = new ArrayList<>(processors.size());
      for (BeanPostProcessor processor : processors) {
         if (processor instanceof DestructionAwareBeanPostProcessor) {
            DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
            if (dabpp.requiresDestruction(bean)) {
               filteredPostProcessors.add(dabpp);
            }
         }
      }
   }
   return filteredPostProcessors;
}

过滤出类型符合DestructionAwareBeanPostProcessor的返回,InitDestroyAnnotationBeanPostProcessor是DestructionAwareBeanPostProcessor的子类

@Nullable
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {

List<BeanPostProcessor> processors 是存储在AbstractBeanFactory中

/** BeanPostProcessors to apply in createBean */
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

返回到这个方法

org.springframework.beans.factory.support.DisposableBeanAdapter#destroy这一行代码

在bean销毁之前进行一些处理
            processor.postProcessBeforeDestruction(this.bean, this.beanName);

进入到这个方法

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction

@Override
   public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
//    找到bean创建和销毁的metadata信息
      LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
      try {
//       执行bean的销毁方法
         metadata.invokeDestroyMethods(bean, beanName);
      }
      catch (InvocationTargetException ex) {
         String msg = "Invocation of destroy method failed on bean with name '" + beanName + "'";
         if (logger.isDebugEnabled()) {
            logger.warn(msg, ex.getTargetException());
         }
         else {
            logger.warn(msg + ": " + ex.getTargetException());
         }
      }
      catch (Throwable ex) {
         logger.error("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
      }
   }
//     找到bean创建和销毁的metadata信息
      LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());

进入这个方法

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;
}

进入这个方法,构建bean的创建、销毁metadata信息

//  构建bean创建和销毁metadata对象
   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 -> {
//           判断方法上是否有@PostConstruct这个注解
            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);
               }
            }
//          @PreDestroy 判断方法上是否有这个注解
            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);

返回到这个方法

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction这行代码

//        执行bean的销毁方法
         metadata.invokeDestroyMethods(bean, beanName);

执行bean的销毁方法

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()) {
            boolean debug = logger.isDebugEnabled();
            for (LifecycleElement element : destroyMethodsToUse) {
               if (debug) {
                  logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
               }
//             执行bean的销毁方法
               element.invoke(target);
            }
         }
      }

最后

本次介绍到这里,以上内容仅供参考。

扫码关注

进群讨论

快到碗里来

!

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1810420
今日推荐