org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton
// 第三步: 将销毁所有的bean
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton
/**
* Destroy the given bean. Delegates to {@code destroyBean}
* if a corresponding disposable bean instance is found.
* @param beanName the name of the bean
* @see #destroyBean
*/
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);
}
destroyBean(beanName, disposableBean);
}
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroyBean
destroyBean(beanName, disposableBean);
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#dependentBeanMap一个bean可以依赖很多个对象
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#containedBeanMap确定该bean是否被其他bean实例引用
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#dependenciesForBeanMapbean所依赖其他bean主要用于beanName导航
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroyBean
/**
* Destroy the given bean. Must destroy beans that depend on the given
* bean before the bean itself. Should not throw any exceptions.
* 在自己销毁之前必须先消费塔索依赖的bean
* @param beanName the name of the bean
* @param bean the bean instance to destroy
*/
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first... 先触发依赖的bean销毁,从本地缓存中删除
// 第一步: 依赖容器
Set<String> dependencies;
// 第二步: 移除bean
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) {
// 这里用了一个递归删除单例bean,当这个bean没有依赖的bean要删除的时候,递归结束
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
// 第三步: 销毁bean
if (bean != null) {
try {
// bean可以实现DisposableBean这个接口,重写父类的bean destory的方法
bean.destroy();
}
catch (Throwable ex) {
if (logger.isInfoEnabled()) {
logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
// 第四步: 包含容器的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) {
// 这个地方还是递归调用,删除单例bean,当这个bean没有内部bean时递归结束
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies. 从其他bean依赖中删除销毁的bean
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. 删除销毁的bean准备的依赖信息
this.dependenciesForBeanMap.remove(beanName);
}
org.springframework.beans.factory.DisposableBean#destroy
bean.destroy();
org.springframework.beans.factory.DisposableBean接口导航
/**
* Interface to be implemented by beans that want to release resources on destruction.
* A {@link BeanFactory} will invoke the destroy method on individual destruction of a
* scoped bean. An {@link org.springframework.context.ApplicationContext} is supposed
* to dispose all of its singletons on shutdown, driven by the application lifecycle.
*
* <p>A Spring-managed bean may also implement Java's {@link AutoCloseable} interface
* for the same purpose. An alternative to implementing an interface is specifying a
* custom destroy method, for example in an XML bean definition. For a list of all
* bean lifecycle methods, see the {@link BeanFactory BeanFactory javadocs}.
*
* @author Juergen Hoeller
* @since 12.08.2003
* @see InitializingBean
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName()
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons()
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
public interface DisposableBean {
/**
* Invoked by the containing {@code BeanFactory} on destruction of a bean.
* @throws Exception in case of shutdown errors. Exceptions will get logged
* but not rethrown to allow other beans to release their resources as well.
*/
void destroy() throws Exception;
}
org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
public void destroy() {
// 第一步: 执行beanPostProcessors,beanPostProcessors用对对bean的过程进行处理的抽象
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
// 第二步: 在bean销毁之前进行一些处理
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) this.bean).destroy();
return null;
}, this.acc);
}
else {
// 第三步: bean实现DisposableBean接口的方式,注解调用子类destroy方法
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.info(msg, ex);
}
else {
logger.info(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
// 执行bean定义中指定的bean销毁方法
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
// 执行bean定义中指定的bean销毁方法
invokeCustomDestroyMethod(methodToCall);
}
}
}
org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
processor.postProcessBeforeDestruction(this.bean, this.beanName);
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction
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 = "Destroy method on bean with name '" + beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#findLifecycleMetadata
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#findLifecycleMetadata
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;
}
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata
// 发生在反序列化
return buildLifecycleMetadata(clazz);
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata
// 构建bean创建和销毁metadata对象
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
//
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
// 方法初始化
List<LifecycleElement> initMethods = new ArrayList<>();
// 销毁方法
List<LifecycleElement> destroyMethods = new ArrayList<>();
// 创建目标类
Class<?> targetClass = clazz;
do {
// 当前初始方法
final List<LifecycleElement> currInitMethods = new ArrayList<>();
// 当前销毁方法
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 判断方法上是否有@PostConstruct这个注解
if (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);
}
}
// @PreDestroy 判断方法上是否有这个注解
if (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));
}
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata#invokeDestroyMethods
metadata.invokeDestroyMethods(bean, beanName);
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata#invokeDestroyMethods
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()) {
for (LifecycleElement element : destroyMethodsToUse) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
}
element.invoke(target);
}
}
}
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleElement#invoke
public void invoke(Object target) throws Throwable {
ReflectionUtils.makeAccessible(this.method);
this.method.invoke(target, (Object[]) null);
}
java.lang.reflect.Method#invoke
this.method.invoke(target, (Object[]) null);