iis发布网站慢,wordpress文件下载页面,全国企业信用公示查询服务平台,网站中搜索关键词1 引入
在 Spring 框架中#xff0c;Bean 的生命周期管理是其核心功能之一#xff0c;而 Bean 的注销#xff08;Destruction#xff09;是生命周期的最后一步。无论是关闭数据库连接、释放线程资源#xff0c;还是执行缓存持久化操作#xff0c;合适的销毁策略都至关重…1 引入
在 Spring 框架中Bean 的生命周期管理是其核心功能之一而 Bean 的注销Destruction是生命周期的最后一步。无论是关闭数据库连接、释放线程资源还是执行缓存持久化操作合适的销毁策略都至关重要。Spring 为 Bean 提供了多种注销方式包括实现特定接口、注解配置和 XML 配置等同时通过源码设计保证了销毁操作的安全性和灵活性。本文将深入剖析 Spring Bean 注销的原理和实现细节并结合源码探讨其调用流程和应用场景。
2 销毁方法的注册
2.1 入口
核心类AbstractBeanFactory.java 核心方法registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {AccessControlContext acc (System.getSecurityManager() ! null ? getAccessControlContext() : null);// 单例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));}}
}
2.2 销毁方法的判断 protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {// bean不能为nullBean// 是否实现DisposableBean接口或者AutoCloseable接口// 是否配置了关于bean销毁的BeanPostProcessorreturn (bean.getClass() ! NullBean.class (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) ||(hasDestructionAwareBeanPostProcessors() DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessorCache().destructionAware))));
} 2.2.1 DisposableBean接口或者AutoCloseable接口 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) {destroyMethodName beanDefinition.getDestroyMethodName();// 如果配置的销毁方法名为(inferred) 或者实现了AutoCloseable接口 或者没有配置销毁方法名称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 DisposableBeandestroyMethodName null;if (!(bean instanceof DisposableBean)) {try {// 是否配置了名为close的方法destroyMethodName bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();}catch (NoSuchMethodException ex) {try {// 是否配置了名为shutdown方法destroyMethodName bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();}catch (NoSuchMethodException ex2) {// no candidate destroy method found}}}}beanDefinition.resolvedDestroyMethodName (destroyMethodName ! null ? destroyMethodName : );}return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
} 2.2.2 DestructionAwareBeanPostProcessor
public static boolean hasApplicableProcessors(Object bean, ListDestructionAwareBeanPostProcessor postProcessors) {if (!CollectionUtils.isEmpty(postProcessors)) {for (DestructionAwareBeanPostProcessor processor : postProcessors) {if (processor.requiresDestruction(bean)) {return true;}}}return false;
}//实现类InitDestroyAnnotationBeanPostProcessor.java
public boolean requiresDestruction(Object bean) {// 判断是否配置了bean销毁的后置处理器return findLifecycleMetadata(bean.getClass()).hasDestroyMethods();
}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;
}private LifecycleMetadata buildLifecycleMetadata(final Class? clazz) {if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {return this.emptyLifecycleMetadata;}ListLifecycleElement initMethods new ArrayList();ListLifecycleElement destroyMethods new ArrayList();Class? targetClass clazz;do {final ListLifecycleElement currInitMethods new ArrayList();final ListLifecycleElement currDestroyMethods new ArrayList();// 遍历方法ReflectionUtils.doWithLocalMethods(targetClass, method - {// 判断是否存在postConstructif (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);}}// 判断是否存在PreDestroyif (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);return (initMethods.isEmpty() destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
3 执行销毁方法
核心类AbstractApplicationContext.java 核心方法doClose 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 {// Publish shutdown event.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 {this.lifecycleProcessor.onClose();}catch (Throwable ex) {logger.warn(Exception thrown from LifecycleProcessor on context close, ex);}}// Destroy all cached singletons in the contexts BeanFactory.//销毁所有的beandestroyBeans();// Close the state of this context itself.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);}
}protected void destroyBeans() {getBeanFactory().destroySingletons();
}public void destroySingletons() {if (logger.isTraceEnabled()) {logger.trace(Destroying singletons in this);}synchronized (this.singletonObjects) {this.singletonsCurrentlyInDestruction true;}String[] disposableBeanNames;synchronized (this.disposableBeans) {disposableBeanNames StringUtils.toStringArray(this.disposableBeans.keySet());}for (int i disposableBeanNames.length - 1; i 0; i--) {// 销毁beandestroySingleton(disposableBeanNames[i]);}this.containedBeanMap.clear();this.dependentBeanMap.clear();this.dependenciesForBeanMap.clear();clearSingletonCache();
}public void destroySingleton(String beanName) {// Remove a registered singleton of the given name, if any.// 先从单例池中移除掉removeSingleton(beanName);// Destroy the corresponding DisposableBean instance.DisposableBean disposableBean;synchronized (this.disposableBeans) {disposableBean (DisposableBean) this.disposableBeans.remove(beanName);}destroyBean(beanName, disposableBean);
}protected void destroyBean(String beanName, Nullable DisposableBean bean) {// dependentBeanMap表示某bean被哪些bean依赖了// 所以现在要销毁某个bean时如果这个Bean还被其他Bean依赖了那么也得销毁其他Bean// Trigger destruction of dependent beans first...SetString dependencies;synchronized (this.dependentBeanMap) {// Within full synchronization in order to guarantee a disconnected Setdependencies 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();}catch (Throwable ex) {if (logger.isWarnEnabled()) {logger.warn(Destruction of bean with name beanName threw an exception, ex);}}}// Trigger destruction of contained beans...SetString containedBeans;synchronized (this.containedBeanMap) {// Within full synchronization in order to guarantee a disconnected SetcontainedBeans this.containedBeanMap.remove(beanName);}if (containedBeans ! null) {for (String containedBeanName : containedBeans) {destroySingleton(containedBeanName);}}// Remove destroyed bean from other beans dependencies.synchronized (this.dependentBeanMap) {for (IteratorMap.EntryString, SetString it this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {Map.EntryString, SetString entry it.next();SetString dependenciesToClean entry.getValue();dependenciesToClean.remove(beanName);if (dependenciesToClean.isEmpty()) {it.remove();}}}// Remove destroyed beans prepared dependency information.this.dependenciesForBeanMap.remove(beanName);
}//实现类DisposableBeanAdapter.java
public void destroy() {if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {// 如果类型是DestructionAwareBeanPostProcessorfor (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}if (this.invokeDisposableBean) {if (logger.isTraceEnabled()) {logger.trace(Invoking destroy() on bean with name this.beanName );}try {// 实现了DisposableBean接口if (System.getSecurityManager() ! null) {AccessController.doPrivileged((PrivilegedExceptionActionObject) () - {((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));}}
}
4 总结 在bean初始化后 会执行销毁方法的注册 注册主要分为两类 一类是实现接口 一类是通过bean的后置处理器 实现DisposableBean接口或者AutoCloseable接口 会直接注册 如果配置了DestructionAwareBeanPostProcessor 并且校验方法返回true 也会添加到注册流程 在容器关闭时 会注销bean 注销时会将注册bean的销毁方法容器取出遍历执行对应的销毁方法