spring源碼解析bean銷燬@PreDestroy

前言spring

本文轉自「天河聊技術」微信公衆號微信

此次主要跟蹤下@PreDestroy這個註解的源碼過程app

 

正文ide

找到這個類post

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor,@PostConstruct和@PreDestroy都是這個類來具體實現的,本次主要介紹@PreDestroy,初始化的後續介紹。ui

 

上篇文章已經介紹過了,在bean銷燬以前會執行到這個方法org.springframework.beans.factory.support.DisposableBeanAdapter#destroythis

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

找到這行代碼debug

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

最後

本次介紹到這裏,以上內容僅供參考。

相關文章
相關標籤/搜索