4.Spring5底层原理之Bean的生命周期
这一节我们学习Bean的生命周期,为了了解Bean的生命周期,我们创建一个SpringBoot的启动类,然后写一个close方法,用来销毁Spring容器,用来观察bean的销毁过程。
@SpringBootApplication
public class A03Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(A03Application.class, args);
context.close();
}
}
然后我们再创建一个类,在这个类的关键部分我们都打了日志,比如构造方法,依赖注入,初始化方法,和销毁方法。这些日志方便我们后续观察bean的生命周期。
@Component
public class LifeCycleBean {
private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);
public LifeCycleBean() {
log.debug("构造");
}
@Autowired
public void autowire(@Value("${JAVA_HOME}") String home) {
log.debug("依赖注入:{}", home);
}
@PostConstruct
public void init() {
log.debug("初始化");
}
@PreDestroy
public void destroy() {
log.debug("销毁");
}
}
前面的文章中我们讲到bean的后处理器,这里我们观察bean的生命周期还会用到bean的后处理器,分别是InstantiationAwareBeanPostProcessor和DestructionAwareBeanPostProcessor后处理器,前者是在bean实例化前后进行处理的后处理器,后者是销毁前进行处理的后处理器。他们都是BeanPostProcessor后处理器接口的子类。
我们同时实现这两个接口,并复写其中的方法。
@Component
public class MyBeanPostprocessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(MyBeanPostprocessor.class);
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 销毁之前执行,如@PreDestroy");
}
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 实例化之前执行,这里返回的对象会替换掉原本的bean");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 实例化之后执行,这里如果返回false会跳过依赖注入阶段");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 依赖注入阶段执行,如@Autowired、@Value、@Resource");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 初始化之前执行,这里返回的对象会替换原本的bean,如@PostConstruct、@ConfigurationProperties");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")){
log.debug("<<< 初始化之后执行,这里返回的对象会替换掉原本的bean,如代理增强");
}
return bean;
}
}
为了让日志不打印过多的内容方便我们观察,在每个方法中都对beanName进行了判断,只有名字是lifeCycleBean才进行日志输出,方便我们进行观察。
我们启动main方法,观察日志输出
2022-04-19 10:20:43.799 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 实例化之前执行,这里返回的对象会替换掉原本的bean
2022-04-19 10:20:43.800 DEBUG 14484 --- [ main] c.z.springsource.a03.LifeCycleBean : 构造
2022-04-19 10:20:43.802 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 实例化之后执行,这里如果返回false会跳过依赖注入阶段
2022-04-19 10:20:43.803 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 依赖注入阶段执行,如@Autowired、@Value、@Resource
2022-04-19 10:20:43.804 DEBUG 14484 --- [ main] c.z.springsource.a03.LifeCycleBean : 依赖注入:C:\Program Files\Java\jdk1.8.0_121
2022-04-19 10:20:43.805 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 初始化之前执行,这里返回的对象会替换原本的bean,如@PostConstruct、@ConfigurationProperties
2022-04-19 10:20:43.805 DEBUG 14484 --- [ main] c.z.springsource.a03.LifeCycleBean : 初始化
2022-04-19 10:20:43.805 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 初始化之后执行,这里返回的对象会替换掉原本的bean,如代理增强
2022-04-19 10:20:44.078 INFO 14484 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-04-19 10:20:44.090 INFO 14484 --- [ main] c.z.springsource.a03.A03Application : Started A03Application in 3.731 seconds (JVM running for 7.211)
2022-04-19 10:20:44.913 DEBUG 14484 --- [ main] c.z.s.a03.MyBeanPostprocessor : <<< 销毁之前执行,如@PreDestroy
2022-04-19 10:20:44.913 DEBUG 14484 --- [ main] c.z.springsource.a03.LifeCycleBean : 销毁
从日志中我们可以发现,bean的生命周期分为:构造 -> 依赖注入->初始化->销毁
我们可以利用后处理器在bean的各个阶段对bean做一些操作。
4.Spring5底层原理之Bean的生命周期
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/spring-bean-life-cycle