所谓 Bean 的生命周期,就是一个 Bean 从创建到销毁,上一篇文章从源码角度解读了Bean生命周期之Bean创建的过程(地址:Spring之Bean生命周期源码解读上),今天我们继续从源码解读Bean的销毁过程。
Bean的销毁过程
Bean销毁是发送在Spring容器关闭过程中的。
在Spring容器关闭时,比如:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = (UserService) context.getBean("userService");userService.test();// 容器关闭context.close();
在Bean创建过程中,在最后(初始化之后),有一个步骤会去判断当前创建的Bean是不是DisposableBean:
- 当前Bean是否实现了DisposableBean接口
- 或者,当前Bean是否实现了AutoCloseable接口
- BeanDefinition中是否指定了destroyMethod
- 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断
a、ApplicationListenerDetector中直接使得ApplicationListener是DisposableBean
b、InitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean
- 把符合上述任意一个条件的Bean适配成DisposableBeanAdapter对象,并存入disposableBeans中(一个LinkedHashMap)
在Spring容器关闭过程:
- 首先发布ContextClosedEvent事件
- 调用lifecycleProcessor的onCloese()方法
- 销毁单例Bean(销毁的单例bean,多例是由JVM回收,因为没有被存储;销毁:就是清空所有的单例map)
- 遍历disposableBeans
1.把每个disposableBean从单例池中移除2.调用disposableBean的destroy()3.如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean4.如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉(inner bean参考:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)
- 清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
- 清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
- 清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean
这里涉及到一个设计模式:适配器模式
在销毁时,Spring会找出实现了DisposableBean接口的Bean。
但是我们在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。
所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。
会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。
Bean销毁源码解读:
public void close() { synchronized (this.startupShutdownMonitor) { // 销毁方法 doClose(); // If we registered a JVM shutdown hook, we don't need it anymore now: // We've already explicitly closed the context. if (this.shutdownHook != null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch (IllegalStateException ex) { // ignore - VM is already shutting down } } }}
protected void doClose() { // Check whether an actual close attempt is necessary... if (this.active.get() && this.closed.compareAndSet(false, true)) { if (logger.isDebugEnabled()) { logger.debug("Closing " + this); } if (!NativeDetector.inNativeImage()) { LiveBeansView.unregisterApplicationContext(this); } try { // 1、发布ContextClosedEvent事件 publishEvent(new ContextClosedEvent(this)); } catch (Throwable ex) { logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex); } // Stop all Lifecycle beans, to avoid delays during individual destruction. if (this.lifecycleProcessor != null) { try { // 2、调用lifecycleProcessor的onCloese()方法 this.lifecycleProcessor.onClose(); } catch (Throwable ex) { logger.warn("Exception thrown from LifecycleProcessor on context close", ex); } } // Destroy all cached singletons in the context's BeanFactory. // 3、销毁BeanFactory中的所有单例Bean destroyBeans(); // Close the state of this context itself. // 销毁bean工厂的所有单例bean closeBeanFactory(); // Let subclasses do some final clean-up if they wish... onClose(); // Reset local application listeners to pre-refresh state. if (this.earlyApplicationListeners != null) { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Switch to inactive. this.active.set(false); }}
销毁BeanFactory中的所有单例Bean源码
protected void destroyBeans() { getBeanFactory().destroySingletons();}public void destroySingletons() { super.destroySingletons(); // 清空manualSingletonNames集合 updateManualSingletonNames(Set::clear, set -> !set.isEmpty()); clearByTypeCache();}
销毁所有的单列bean
public void destroySingletons() { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this); } synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } // 1.把每个disposableBean从单例池中移除(取出的是beanName) String[] disposableBeanNames; synchronized (this.disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } // 2.遍历disposableBeans for (int i = disposableBeanNames.length - 1; i >= 0; i--) { // 3.调用disposableBean的destroy()方法执行定义的销毁方法 destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); clearSingletonCache();}
销毁单列bean
public void destroySingleton(String beanName) { // Remove a registered singleton of the given name, if any. // 删除单列bean removeSingleton(beanName); // Destroy the corresponding DisposableBean instance. DisposableBean disposableBean; synchronized (this.disposableBeans) { disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } // 销毁单列bean destroyBean(beanName, disposableBean);}
如果disposableBean还被其他Bean依赖了,那么也得销毁其他Bean。
protected void destroyBean(String beanName, @Nullable DisposableBean bean) { // dependentBeanMap表示某bean被哪些bean依赖了 // 所以现在要销毁某个bean时,如果这个Bean还被其他Bean依赖了,那么也得销毁其他Bean // Trigger destruction of dependent beans first... Set<String> dependencies; synchronized (this.dependentBeanMap) { // Within full synchronization in order to guarantee a disconnected Set dependencies = this.dependentBeanMap.remove(beanName); } if (dependencies != null) { if (logger.isTraceEnabled()) { logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } // Actually destroy the bean now... if (bean != null) { try { // 执行bean的destroy()方法,在销毁之前会执行执行postProcessBeforeDestruction()方法, // 这是一个bean销毁的扩展点,我们可以在bean销毁之前做一些其他事情。比如:销毁之前关闭其他的一些服务等。 bean.destroy(); } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex); } } } // Trigger destruction of contained beans... Set<String> containedBeans; synchronized (this.containedBeanMap) { // Within full synchronization in order to guarantee a disconnected Set containedBeans = this.containedBeanMap.remove(beanName); } if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); } } // Remove destroyed bean from other beans' dependencies. synchronized (this.dependentBeanMap) { for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) { Map.Entry<String, Set<String>> entry = it.next(); Set<String> dependenciesToClean = entry.getValue(); dependenciesToClean.remove(beanName); if (dependenciesToClean.isEmpty()) { it.remove(); } } } // Remove destroyed bean's prepared dependency information. // 从dependenciesForBeanMap移除bean this.dependenciesForBeanMap.remove(beanName);}
这里是要执行的postProcessBeforeDestruction()方法的源码
public interface DisposableBean { void destroy() throws Exception;}
DisposableBean的实现类DisposableBeanAdapter,其中对destroy()方法的实现源码
public void destroy() { if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { // 执行postProcessBeforeDestruction()方法 processor.postProcessBeforeDestruction(this.bean, this.beanName); } } if (this.invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'"); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { // 执行DisposableBean的destroy()方法 ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.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) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } }}
自定义bean的销毁逻辑
在bean的创建过程中,可以自定义bean的销毁逻辑,在bean的创建源码doCreateBean()方法中
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { ...... try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } }
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); // isPrototype() :判断bean是否单例; // requiresDestruction():判断bean是否有定义的销毁逻辑;是否需要执行某些额外的方法 if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter( bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter( bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc)); } }}
判断bean是否有定义的销毁逻辑,是否需要执行某些额外的requiresDestruction()方法源码
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { // DisposableBeanAdapter.hasDestroyMethod():判断是否有定义的销毁逻辑; // 获取Spring定义的销毁逻辑: // DestructionAwareBeanPostProcessor接口的两个方法: // postProcessBeforeDestruction:销毁前 // requiresDestruction:销毁bean return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors( bean, getBeanPostProcessorCache().destructionAware))));}
DisposableBeanAdapter.hasDestroyMethod():判断是否有定义的销毁逻辑源码
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) { if (bean instanceof DisposableBean || bean instanceof AutoCloseable) { return true; } return inferDestroyMethodIfNecessary(bean, beanDefinition) != null;}
private static String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) { String destroyMethodName = beanDefinition.resolvedDestroyMethodName; if (destroyMethodName == null) { // 获取beanDefinition的销毁方法 destroyMethodName = beanDefinition.getDestroyMethodName(); // 销毁方法不是:inferred if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) || (destroyMethodName == null && bean instanceof AutoCloseable)) { // Only perform destroy method inference or Closeable detection // in case of the bean not explicitly implementing DisposableBean destroyMethodName = null; if (!(bean instanceof DisposableBean)) { try { // beanDefinition中的close方法指定为我销毁方法 destroyMethodName = bean.getClass().getMethod(CLOSE_METHOD_NAME).getName(); } catch (NoSuchMethodException ex) { try { // beanDefinition中的shutdown方法指定为我销毁方法 destroyMethodName = bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName(); } catch (NoSuchMethodException ex2) { // no candidate destroy method found } } } } // 存储beanDefinition的销毁方法 beanDefinition.resolvedDestroyMethodName = (destroyMethodName != null ? destroyMethodName : ""); } return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);}
postProcessBeforeDestruction:销毁前源码
protected boolean hasDestructionAwareBeanPostProcessors() { return !getBeanPostProcessorCache().destructionAware.isEmpty();}
equiresDestruction:销毁bean源码
public static boolean hasApplicableProcessors(Object bean, List<DestructionAwareBeanPostProcessor> postProcessors) { if (!CollectionUtils.isEmpty(postProcessors)) { for (DestructionAwareBeanPostProcessor processor : postProcessors) { if (processor.requiresDestruction(bean)) { return true; } } } return false;}
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除