Spring的生命周期主要指创建、初始化、销毁。Bean的生命周期主要由容器进行管理,我们可以自定义bean的初始化和销毁方法,容器在bean进行到生命周期的特定时间点,来调用自定义的初始化和销毁方法。
示例代码地址:
一 初始化和销毁方式
1.1 指定初始化前方法和容器销毁后方法
init-method destory-method
单实例bean下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean
package com.;
import lombok.ex;
import org.;
/**
* \* Created with IntelliJ IDEA.
* \* @author: wucj
* \* @date: 2020/9/16 12:58
* \* @description:
* \
*/
@Slf4j
public class CycleOne {
public CycleOne() {
log.info("{}...constructor...",().getSimpleName());
}
public void init(){
log.info("{}...init...",().getSimpleName());
}
public void destory(){
log.info("{}...destory...",().getSimpleName());
}
}
1.2 让Bean实现InitializingBean, DisposableBean 接口
package com.;
import lombok.ex;
import org.;
import org.;
/**
* \* Created with IntelliJ IDEA.
* \* @author: wucj
* \* @date: 2020/9/16 12:58
* \* @description:
* \
*/
@Slf4j
public class CycleTwo implements InitializingBean, DisposableBean {
public CycleTwo() {
log.info("{}...constructor...", ().getSimpleName());
}
// 容器移除对象之后调用
@Override
public void destroy() throws Exception {
log.info("{}...destroy...", ().getSimpleName());
}
// 对象创建并赋值完成之后调用
@Override
public void afterPropertiesSet() throws Exception {
log.info("{}...afterPropertiesSet...", ().getSimpleName());
}
}
1.3 使用jsr250规则(java规范)定义的两个注解来实现
package com.;
import lombok.ex;
import javax.anno;
import javax.anno;
/**
* \* Created with IntelliJ IDEA.
* \* @author: wucj
* \* @date: 2020/9/16 12:58
* \* @description:
* \
*/
@Slf4j
public class CycleThree{
public CycleThree() {
log.info("{}...constructor...", ().getSimpleName());
}
// 容器移除对象之后调用
@PreDestroy
public void methord1(){
log.info("{}...destroy...", ().getSimpleName());
}
// 对象创建并赋值完成之后调用
@PostConstruct
public void methord2() {
log.info("{}...afterPropertiesSet...", ().getSimpleName());
}
}
bean注入到容器中:
package com.;
import com..CycleOne;
import com..CycleThree;
import com..CycleTwo;
import org.;
import org.;
import org.;
/**
* \* Created with IntelliJ IDEA.
* \* @author: wucj
* \* @date: 2020/9/16 12:57
* \* @description:
* \
*/
@Configuration
// 扫描指定包路径下的所有bean
@ComponentScan("com.")
public class CycleConfig {
/**
* 自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
* 注意1:单实例下可以调用实例的initMethod和destoryMethod方法,多实例无法调用。
* 注意2:
* @return
*/
@Bean(initMethod = "init",destroyMethod = "destory")
// 多实例不能调用initMethod和destoryMetod方法
// @Scope("prototype")
public CycleOne cycleOne(){
return new CycleOne();
}
@Bean
public CycleTwo cycleTwo(){
return new CycleTwo();
}
@Bean
public CycleThree cycleThree(){
return new CycleThree();
}
}
容器启动和销毁:
package com.;
import com..CycleConfig;
import org.;
/**
* \* Created with IntelliJ IDEA.
* \* @author: wucj
* \* @date: 2020/9/16 13:01
* \* @description: bean生命周期源码跟踪与学习
* \
*/
public class CycleConfigTest {
public static void main(String[] args) {
// 启动容器
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContex);
/**
* 注意1:单实例下自定义bean的初始化和销毁方法,在容器关闭时会调用当前bean的initMethod和destoryMethod方法
* 注意2:多实例bean 只有在调用getBean(name)时才会初始化bean,并且容器不会管理多实例bean,所以容器关闭时,不会调用bean的自定义初始化和销毁bean
* @return
*/
// 关闭容器
a();
}
}
只有以上三种可以实现bean的自定义初始化和销毁调用;
二 后置处理器
后置处理器负责在初始化方法前后调用;
接口BeanPostProcessor是bean的后置处理器,在bean初始化前、后进行方法拦截;
方法1:
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
调用时机:在任何初始化方法调用之前进行后置处理工作(initMethod之前、initializingBean的afterPropertiesSet初始化之前)
方法2:
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
调用时机:在任何初始化方法调用之后进行后置处理工作(initMethod之后、initializingBean的afterPropertiesSet初始化之后)
总结:单实例bean的整个生命周期都可以进行控制;
三 容器启动及BeanPostProcessor源码分析
针对CycleConfigTest进行debug:以下所有断点位置都是源码的位置,请使用示例源码项目断点:下载
断点1:org/springframework/context/annotation
refresh();
断点2:org/springframework/context/suppor
// Instantiate all remaining (non-lazy-init) singletons. 实例化非懒加载单例bean
finishBeanFactoryInitialization(beanFactory);
断点3:org/springframework/context/suppor
// Instantiate all remaining (non-lazy-init) singletons.
beanFac();
断点4:org/springframework/beans/factory/suppor
getBean(beanName);
断点5:org/springframework/beans/factory/suppor
return doGetBean(name, null, null, false);
断点6:org/springframework/beans/factory/suppor
断点7:org/springframework/beans/factory/suppor
断点8:org/springframework/beans/factory/suppor
return createBean(beanName, mbd, args);
断点9:org/springframework/beans/factory/suppor
断点10:org/springframework/beans/factory/suppor
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
断点11:org/springframework/beans/factory/suppor
断点12:org/springframework/beans/factory/suppor
populateBean(beanName, mbd, instanceWrapper); // 属性赋值
exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化
断点13:org/springframework/beans/factory/suppor
// 初始化方法调用之前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
断点14:org/springframework/beans/factory/suppor
// 初始化
invokeInitMethods(beanName, wrappedBean, mbd);
断点15:org/springframework/beans/factory/suppor
// 初始化方法调用后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);