Spring源码解析之bean的销毁

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/heroqiang/article/details/81541208

阅读须知

  • Spring源码版本:4.3.8
  • 文章中使用/* */注释的方法会做深入分析

正文

我们来看几个销毁bean的场景,在一些异常情况,例如Spring上下文初始化失败时,会销毁已经创建的单例bean,这时会调用相关销毁方法,在Spring容器关闭时,同样会调用disposableBeans的销毁方法:
AbstractApplicationContext:

public void registerShutdownHook() {
    if (this.shutdownHook == null) {
        this.shutdownHook = new Thread() {
            @Override
            public void run() {
                synchronized (startupShutdownMonitor) {
                    /* 关闭容器 */
                    doClose();
                }
            }
        };
        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
}

AbstractApplicationContext:

public void close() {
    synchronized (this.startupShutdownMonitor) {
        /* 关闭容器 */
        doClose();
        if (this.shutdownHook != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
            }
            catch (IllegalStateException ex) {
            }
        }
    }
}

在容器注册的关闭钩子的关闭方法中都调用了doClose方法,我们来分析这个方法:

protected void doClose() {
    // 判断active激活标记(在初始化上下文时被设置为true用于标记激活状态)并且将closed标记设置为true
    if (this.active.get() && this.closed.compareAndSet(false, true)) {
        if (logger.isInfoEnabled()) {
            logger.info("Closing " + this);
        }
        // 卸载注册的JMX的MBean
        LiveBeansView.unregisterApplicationContext(this);
        try {
            // 发布容器关闭事件
            publishEvent(new ContextClosedEvent(this));
        }
        catch (Throwable ex) {
            logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
        }
        try {
            // 调用实现了Lifecycle的bean的stop方法,关于Lifecycle,我们在标签解析的文章中分析过
            getLifecycleProcessor().onClose();
        }
        catch (Throwable ex) {
            logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
        }
        /* 销毁bean */
        destroyBeans();
        // 关闭BeanFactory,将BeanFactory序列化id和本身置为null
        closeBeanFactory();
        // 子类扩展
        onClose();
        // 将激活标记置为false
        this.active.set(false);
    }
}

AbstractApplicationContext:

protected void destroyBeans() {
    // 销毁单例bean
    getBeanFactory().destroySingletons();
}

DefaultListableBeanFactory:

public void destroySingletons() {
    /* 调用父类的销毁方法销毁单例bean */
    super.destroySingletons();
    // 清空手工注册的beanName的缓存
    this.manualSingletonNames.clear();
    // 清空类型-->beanName的映射缓存
    clearByTypeCache();
}

DefaultSingletonBeanRegistry:

public void destroySingletons() {
    if (logger.isDebugEnabled()) {
        logger.debug("Destroying singletons in " + this);
    }
    synchronized (this.singletonObjects) {
        // 设置正在销毁的标记为true
        this.singletonsCurrentlyInDestruction = true;
    }
    String[] disposableBeanNames;
    synchronized (this.disposableBeans) {
        disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    }
    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
        /* 遍历销毁之前注册的所有disposableBean */
        destroySingleton(disposableBeanNames[i]);
    }
    // 清空beanName --> 它包含的所有内部beanName集合的映射缓存
    this.containedBeanMap.clear();
    // 清空beanName --> 它依赖的所有beanName集合的映射缓存
    this.dependentBeanMap.clear();
    // 清空beanName --> 依赖它的所有beanName集合的映射缓存
    this.dependenciesForBeanMap.clear();
    synchronized (this.singletonObjects) {
        // 清空单例bean缓存
        this.singletonObjects.clear();
        // 清空单例工厂缓存
        this.singletonFactories.clear();
        // 清空提前暴露的beanName --> bean的映射缓存
        this.earlySingletonObjects.clear();
        // 清空已经注册的单例bean缓存
        this.registeredSingletons.clear();
        // 设置正在销毁的标记为false
        this.singletonsCurrentlyInDestruction = false;
    }
}

DefaultSingletonBeanRegistry:

public void destroySingleton(String beanName) {
    // 清除bean的相应缓存
    removeSingleton(beanName);
    DisposableBean disposableBean;
    synchronized (this.disposableBeans) {
        // 移除并获取disposableBean
        disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
    }
    /* 销毁 */
    destroyBean(beanName, disposableBean);
}

DefaultSingletonBeanRegistry:

protected void destroyBean(String beanName, DisposableBean bean) {
    Set<String> dependencies = this.dependentBeanMap.remove(beanName);
    if (dependencies != null) {
        if (logger.isDebugEnabled()) {
            logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
        }
        for (String dependentBeanName : dependencies) {
            // 首选递归销毁所有当前bean依赖的bean
            destroySingleton(dependentBeanName);
        }
    }
    if (bean != null) {
        try {
            // 调用destory方法
            bean.destroy();
        }
        catch (Throwable ex) {
            logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
        }
    }
    Set<String> containedBeans = this.containedBeanMap.remove(beanName);
    if (containedBeans != null) {
        for (String containedBeanName : containedBeans) {
            // 递归销毁当前bean包含的所有内部bean
            destroySingleton(containedBeanName);
        }
    }
    synchronized (this.dependentBeanMap) {
        // 遍历找出所有依赖当前bean的列表,将当前bean从被依赖的列表中移除
        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();
            }
        }
    }
    // 从所有依赖当前bean的映射中移除依赖关系
    this.dependenciesForBeanMap.remove(beanName);
}

整个Spring销毁bean的流程到这里就结束了。

猜你喜欢

转载自blog.csdn.net/heroqiang/article/details/81541208
今日推荐