参考文章:
关于Bean的生命周期,我们先看一张图,这张图标识Bean创建和销毁的流程
从上图,我们可以看到整个流程是:
- bean实例化:创建bean
- bean实例化:注入属性
- 激活Aware
- BeanPostProcessor 前置
- 初始化init方法
- BeanPostProcessor 后置
- 使用销毁方法
其中bean实例化的内容我们在
- bean实例化:创建bean
- bean实例化:注入属性
spring学习(五)——Bean的创建中已经学习
3.激活Aware
4.BeanPostProcessor 前置
5.初始化init方法
6.BeanPostProcessor 后置
DisposableBean和
destroy-method
则用于对象的自定义销毁工作,当完成调用后,如果是 singleton 类型的 bean ,则会看当前 bean 是否应实现了 DisposableBean 接口或者配置了destroy-method
属性,如果是的话,则会为该实例注册一个用于对象销毁的回调方法,便于在这些 singleton 类型的 bean 对象销毁之前执行销毁逻辑。
- 对于 BeanFactory 容器而言,我们需要主动调用
#destroySingletons()
方法,通知 BeanFactory 容器去执行相应的销毁方法。 - 对于 ApplicationContext 容器而言,调用
#registerShutdownHook()
方法。
demo
首先定义一个类,实现上述接口
public class LifeCycleBeanTest implements
BeanNameAware, //BeanName 的 Aware
BeanFactoryAware, //BeanFactory 的 Aware
BeanClassLoaderAware,//BeanClassLoader 的 Aware
BeanPostProcessor,//后置
InitializingBean,//初始化方法的
DisposableBean {//销毁的
private String name;
public LifeCycleBeanTest(){ // 构造方法
System.out.println("构造函数调用...");
}
public void display(){
System.out.println("方法调用...");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("setBeanClassLoader 被调用...");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory 被调用...");
}
@Override
public void setBeanName(String s) {
System.out.println("setBeanName 被调用...");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessBeforeInitialization 被调用...");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor postProcessAfterInitialization 被调用...");
return bean;
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean destroy 被调动...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet 被调动...");
}
public void initMethod(){
System.out.println("init-method 被调用...");
}
public void destroyMethdo(){
System.out.println("destroy-method 被调用...");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("属性注入....");
this.name = name;
}
}
xml中配置该类
<bean id="lifeCycle" class="com.learn.initbean.lifecycle.LifeCycleBeanTest"
init-method="initMethod" destroy-method="destroyMethdo">
<property name="name" value="xml名字"/>
</bean>
</beans>
spring加载配置
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("spring5.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
// BeanFactory 容器一定要调用该方法进行 BeanPostProcessor 注册
factory.addBeanPostProcessor(new LifeCycleBeanTest()); // <1>
LifeCycleBeanTest lifeCycleBean = (LifeCycleBeanTest) factory.getBean("lifeCycle");
lifeCycleBean.display();
System.out.println("方法调用完成,容器开始关闭....");
// 关闭容器
factory.destroySingletons();
}
打印结果
16:00:55.693 [main] DEBUG org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader - Loading bean definitions
构造函数调用...
16:00:55.742 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'lifeCycle'
16:00:55.743 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'lifeCycle'
构造函数调用...
16:00:55.767 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'lifeCycle' to allow for resolving potential circular references
Disconnected from the target VM, address: '127.0.0.1:59012', transport: 'socket'
属性注入....
setBeanName 被调用...
setBeanClassLoader 被调用...
setBeanFactory 被调用...
BeanPostProcessor postProcessBeforeInitialization 被调用...
16:00:55.887 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'lifeCycle'
InitializingBean afterPropertiesSet 被调动...
16:00:55.887 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking init method 'initMethod' on bean with name 'lifeCycle'
init-method 被调用...
BeanPostProcessor postProcessAfterInitialization 被调用...
16:00:55.891 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'lifeCycle'
方法调用...
方法调用完成,容器开始关闭....
16:00:55.892 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17a7f733: defining beans [lifeCycle]; root of factory hierarchy
16:00:55.892 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy() on bean with name 'lifeCycle'
DisposableBean destroy 被调动...
16:00:55.892 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy method 'destroyMethdo' on bean with name 'lifeCycle'
destroy-method 被调用...
Spring Bean 的生命周期总结
- Spring 容器根据实例化策略对 Bean 进行实例化。
- 实例化完成后,如果该 bean 设置了一些属性的话,则利用 set 方法设置一些属性。
- 如果该 Bean 实现了 BeanNameAware 接口,则调用
#setBeanName(String beanName)
方法。 - 如果该 bean 实现了 BeanClassLoaderAware 接口,则调用
setBeanClassLoader(ClassLoader classLoader)
方法。 - 如果该 bean 实现了 BeanFactoryAware接口,则调用
setBeanFactory(BeanFactory beanFactory)
方法。 - 如果该容器注册了 BeanPostProcessor,则会调用
#postProcessBeforeInitialization(Object bean, String beanName)
方法,完成 bean 前置处理 - 如果该 bean 实现了 InitializingBean 接口,则调用
#afterPropertiesSet()
方法。 - 如果该 bean 配置了
init-method
方法,则调用其指定的方法。 - 初始化完成后,如果该容器注册了 BeanPostProcessor 则会调用
#postProcessAfterInitialization(Object bean, String beanName)
方法,完成 bean 的后置处理。 - 对象完成初始化,开始方法调用。
- 在容器进行关闭之前,如果该 bean 实现了 DisposableBean 接口,则调用
#destroy()
方法。 - 在容器进行关闭之前,如果该 bean 配置了
destroy-method
,则调用其指定的方法。
demo项目地址
https://gitee.com/daifylearn/springLearn