Spring 生命周期之 Bean 销毁

Bean 销毁

Posted by 王明高 on March 24, 2020

1 Spring Bean 销毁阶段划分

  • Bean 销毁前阶段
  • Bean 销毁阶段
  • Bean 垃圾回收(GC)

2 Spring Bean 销毁各阶段详细分析

2.1 Bean 销毁前阶段

DestructionAwareBeanPostProcessor#postProcessBeforeDestruction

2.1.1 代码示例

...
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor{

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {

        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) 
    }
}    

2.1.2 源码讲解

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
...
    @Override
	public void destroyBean(String beanName, Object beanInstance) {
		destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
	}
...
    protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
		new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
	}
...    
}
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
...
@Override
	public void destroy() {
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}
		...
	}    
...
}

2.2 Bean 销毁阶段

  • @PreDestroy 标准方法
  • 实现 DisposableBean 接口的 destroy() 方法
  • 自定义销毁方法

2.2.1 代码示例

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/beans/spring-context.xsd">

    <bean class="org.wmg.thinking.in.spring.bean.lifecycle.MyInstantiationAwareBeanPostProcessor" />

    <bean id = "userHolder" class="org.wmg.thinking.in.spring.bean.lifecycle.UserHolder" autowire="constructor" destroy-method="doDestroy">
        <!-- 通过 XML 元素配置 -->
        <property name="description" value="the user holder" />
    </bean>
</beans>
public class UserHolder implements DisposableBean {
    ...
    @PreDestroy
    public void preDestroy() {

        // postProcessBeforeDestruction() = the user holder v9
        this.description = "the user holder v10";
        System.out.println("preDestroy() = " + description);
    }

    @Override
    public void destroy() throws Exception {

        // preDestroy() = "the user holder v11";
        this.description = "the user holder v11";
        System.out.println("destroy() = " + description);
    }

    public void doDestroy(){

        // destroy = "the user holder v12";
        this.description = "the user holder v12";
        System.out.println("doDestroy() = " + description);
    }
    ...
}

2.2.2 源码讲解

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
...
    @Override
	public void destroyBean(String beanName, Object beanInstance) {
		destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
	}
...
    protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
		new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
	}
...    
}
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
...
@Override
	public void destroy() {
		...
        if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
    	...
	}    
...
}

2.3 Bean 垃圾回收(GC)

  • 关闭 Spring 容器(应用上下文)
  • 执行 GC
  • Spring Bean 覆盖 finalize() 方法被回调

2.3.1 代码示例

public class UserHolder implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware,
        InitializingBean, SmartInitializingSingleton, DisposableBean {
 	...
    protected void finalize() throws Throwable {

        System.out.println("UserHolder is finalzied...");
    }
 }
public class BeanLifecycleDemo {

    public static void main(String[] args) throws InterruptedException {

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        // 添加 MyDestructionAwareBeanPostProcessor 执行销毁前回调
        beanFactory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
        // 添加 CommonAnnotationBeanPostProcessor 解决 @PostConstructor
        beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
        // 基于 XML 资源 BeanDefinitionReader 实现
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        String[] locations = {"META-INF/dependency-lookup-context.xml",
                "META-INF/bean-constructor-dependency-injection.xml"};
        int beanNumbers = beanDefinitionReader.loadBeanDefinitions(locations);
        System.out.println("已加载 BeanDefinition 数量:" + beanNumbers);

        // 显示执行 preInstantiateSingletons()
        // SmartInitliziingSingleton 通常在 Spring ApplicationContext 场景使用。
        // preInstantiateSingletons() 将已注册的 BeanDefinition 初始化成 Spring Bean
        beanFactory.preInstantiateSingletons();

        // 通过 Bean id 和类型进行依赖查找
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);

        User superUser = beanFactory.getBean("superUser", User.class);
        System.out.println(superUser);

        // 构造器注入按照类型注入,resolveDependency
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);

        //执行 Bean 销毁(容器内)
        beanFactory.destroyBean("userHolder", userHolder);
        // Bean  销毁并不意味着 Bean 垃圾回收了
        System.out.println(userHolder);

        // 销毁 BeanFactory 中的单例 Bean
        beanFactory.destroySingletons();;

        //强制 GC
        System.gc();

        // 等待一段时间
        Thread.sleep(1000L);

        //强制 GC
        System.gc();
    }
}