想要查看前面的笔记请翻阅我的CSDN博客,作者码字不易,喜欢的话点赞,加个关注吧,后期还有很多干货等着你!
bean的生命周期
- 创建
- 后置处理器
- 初始化
- 后置处理器
- 销毁
一、Bean指定初始化和销毁方法
- 指定初始化和销毁方法
在上一章使用@Configuration和@Bean注解搭配进行Bean注册时,@Bean注解上可以使用两个属性:initMethod以及destroyMethod,指定注册Bean的两个方法为初始化和销毁方法。
注意:单实例Bean是在容器启动时创建对象,当对象创建好后(包含对象赋值操作)调用指定的initMethod,多实例Bean是在获取时创建对象,当对象创建好后(包含对象赋值操作)调用指定的initMethod,单实例Bean是在容器销毁时调用destroyMethod,多实例Bean是不调用destroyMethod的。
-
实现接口(InitializingBean)与接口(DisposableBean)
InitializingBean:初始化,对应实现方法(afterPropertiesSet)在对象属性赋值之后触发
DisposableBean:销毁单实例,对应实现方法(destroy)销毁时触发 -
使用JSR250规范中的注解
@PostConstruct:在beann创建完成并且属性赋值完成,来执行初始化方法
@PreDestroy:在容器销毁Bean之前,执行销毁方法
二、后置处理器
-
后置处理器接口
BeanPostProcessor接口 :在Bean的初始化前后进行一些处理工作
其中有两个方法需要实现:
postProcessBeforeInitialization(返回值为初始化的Bean):在初始化之前执行
postProcessAfterInitialization(返回值为初始化的Bean):在初始化之后执行 -
Bean的初始化后置处理器的原理
spring底层调用:
- 先调用:populateBean(像对象赋值)
- 再调用:initializeBean(初始化方法)
initializeBean方法内部:
- 后置处理器在初始化之间执行方法:applyBeeanPostProcessorsBeforeInitialization
- 执行初始化方法:invokeInitMethods
- 后置处理器在初始化之间执行方法:applyBeeanPostProcessorsAfterInitialization
applyBeeanPostProcessorsBeforeInitialization方法中获取实现了BeanPostProcessor接口的所有对象,进行forEach遍历,调用每一个postProcessBeforeInitialization。当有一个BeanPostProcessor的postProcessBeforeInitialization返回为null时,整个方法就会跳出。applyBeeanPostProcessorsAfterInitialization同理。
- 后置处理器在Spring中的应用
XXXXAware都是通过后置处理器实现的,比如在spring底层的ApplicationContextAwareProcessor(获取ioc容器),这个类实现了BeanPostProcessor,实现方法postProcessBeforeInitialization,实现内容是去判断当前的bean是哪种类型(使用instanceof,比如bean instanceof EnvironmentAware),当实现了这些接口时:就调用invokeAwareInterfaces,对应需要的值注入过去。
AutowiredAnnotationBeanPostProcessor:处理@Autowired注解的后置处理器,将标注了这个注解的Bean注入到对应的类中。
@Async也是通过后置处理器去处理的。
package com.ruoyi.project.imcong.service.impl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class abd implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//注意是先调用对象赋值(populateBean),所以可以在这里获取到容器
String applicationName = applicationContext.getApplicationName();
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}