前言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); } } }
最後
本次介紹到這裏,以上內容僅供參考。