spring bean 分为4个大的阶段
然后围绕这4个阶段,有相应的阶段处理接口。
实现InstantiationAwareBeanPostProcessor接口
1.围绕实例化 Instantiation 有
@Override
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
if(beanClass.isAssignableFrom(MyBean.class)){
log.info("1-Instantiation-Before 实例化前回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("1-Instantiation-After实例化后回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法");
}
return true;
}
2.围绕属性赋值 Populate 有
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("2.在bean的属性设置后调");
}
return null;
}
3.围绕初始化 Initialization 有
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("3-Initialization-After 初始化后回调方法:实现BeanPostProcessor接口的postProcessAfterInitialization方法");
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("3-Initialization-Before 调用BeanPostProcessor的postProcessBeforeInitialization方法,beanName=" + beanName);
}
return bean;
}
实现InitializingBean接口,围绕初始化 Initialization 有
/**
* 3.初始化前回调方法:实现InitializingBean接口或使用@PostConstruct注解
*/
@Override
public void afterPropertiesSet() throws Exception {
log.info("3.初始化:实现InitializingBean接口或在XML中配置init-method属性 重写afterPropertiesSet方法");
if (name == null) {
//1.检查必需属性:如果一个类有必须属性,而这些属性可能在Bean构造函数或属性设置器中未被设置,
// 那么可以使用 afterPropertiesSet() 方法来检查这些属性是否都被正确地设置了
//2.创建依赖关系
throw new IllegalArgumentException("name must be set");
}
}
@PostConstruct
private void init() {
// initialization logic here
log.info("3-Initialization.初始化回调方法:使用@PostConstruct注解");
//1.初始化资源:如果您的Bean需要完成某些耗时的初始化操作,例如读取配置文件、建立数据库连接等,
// 那么可以使用 @PostConstruct 注解在Bean属性设置完毕后进行处理,以确保Bean的属性被正确地设置并且准备就绪。
//2.注册监听器:在Bean准备就绪后,可能需要注册一些监听器以便它们可以处理事件。
}
实现InitializingBean接口,围绕销毁 Destruction 有
@Override
public void destroy() throws Exception {
/**
* 用于在 Spring 容器销毁 bean 之前执行相关的资源清理工作
*/
log.info("7.销毁前回调方法:实现DisposableBean接口");
}
@PreDestroy
private void destroy2() {
// destruction logic here
/**
* 可以在 bean 销毁之前进行资源的清理和释放等工作。
*/
log.info("7.销毁前回调方法:使用@PreDestroy注解");
}
测试代码
MyBean对象
@Data
@Slf4j
@Service
public class MyBean implements InitializingBean, DisposableBean {
private String name;
public MyBean() {
log.info("1-Instantiation.实例化:使用构造函数来创建Bean实例");
this.name = "HELLO";
}
public MyBean(String name ) {
this.name = name;
log.info("6.使用:在程序中使用Bean对象"+name);
}
/**
* 3.初始化前回调方法:实现InitializingBean接口或使用@PostConstruct注解
*/
@Override
public void afterPropertiesSet() throws Exception {
log.info("3.初始化:实现InitializingBean接口或在XML中配置init-method属性 重写afterPropertiesSet方法");
if (name == null) {
//1.检查必需属性:如果一个类有必须属性,而这些属性可能在Bean构造函数或属性设置器中未被设置,
// 那么可以使用 afterPropertiesSet() 方法来检查这些属性是否都被正确地设置了
//2.创建依赖关系
throw new IllegalArgumentException("name must be set");
}
}
@PostConstruct
private void init() {
// initialization logic here
log.info("3-Initialization.初始化回调方法:使用@PostConstruct注解");
//1.初始化资源:如果您的Bean需要完成某些耗时的初始化操作,例如读取配置文件、建立数据库连接等,
// 那么可以使用 @PostConstruct 注解在Bean属性设置完毕后进行处理,以确保Bean的属性被正确地设置并且准备就绪。
//2.注册监听器:在Bean准备就绪后,可能需要注册一些监听器以便它们可以处理事件。
}
@Override
public void destroy() throws Exception {
/**
* 用于在 Spring 容器销毁 bean 之前执行相关的资源清理工作
*/
log.info("7.销毁前回调方法:实现DisposableBean接口");
}
@PreDestroy
private void destroy2() {
// destruction logic here
/**
* 可以在 bean 销毁之前进行资源的清理和释放等工作。
*/
log.info("7.销毁前回调方法:使用@PreDestroy注解");
}
}
MyBeanPostProcessor类
@Slf4j
@Configuration
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
*InstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor
*/
@Override
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
if(beanClass.isAssignableFrom(MyBean.class)){
log.info("1-Instantiation-Before 实例化前回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("1-Instantiation-After实例化后回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法");
}
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("2.在bean的属性设置后调");
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("3-Initialization-After 初始化后回调方法:实现BeanPostProcessor接口的postProcessAfterInitialization方法");
}
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MyBean) {
log.info("3-Initialization-Before 调用BeanPostProcessor的postProcessBeforeInitialization方法,beanName=" + beanName);
}
return bean;
}
}
用spring启动
@RunWith(SpringRunner.class)
@SpringBootTest
public class BeanTest1 {
@Test
public void aa() throws Exception {
System.out.println("使用有参构造:"+new MyBean("mary"));
}
}
输出
2023-04-04 15:51:39.682 INFO 44460 --- [ main] c.e.d.beanLifeTest.MyBeanPostProcessor : 1-Instantiation-Before 实例化前回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法
2023-04-04 15:51:39.682 INFO 44460 --- [ main] com.example.demo.beanLifeTest.MyBean : 1-Instantiation.实例化:使用构造函数来创建Bean实例
2023-04-04 15:51:39.684 INFO 44460 --- [ main] c.e.d.beanLifeTest.MyBeanPostProcessor : 1-Instantiation-After实例化后回调方法:实现InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法
2023-04-04 15:51:39.686 INFO 44460 --- [ main] c.e.d.beanLifeTest.MyBeanPostProcessor : 2.在bean的属性设置后调
2023-04-04 15:51:39.686 INFO 44460 --- [ main] c.e.d.beanLifeTest.MyBeanPostProcessor : 3-Initialization-Before 调用BeanPostProcessor的postProcessBeforeInitialization方法,beanName=myBean
2023-04-04 15:51:39.686 INFO 44460 --- [ main] com.example.demo.beanLifeTest.MyBean : 3-Initialization.初始化回调方法:使用@PostConstruct注解
2023-04-04 15:51:39.686 INFO 44460 --- [ main] com.example.demo.beanLifeTest.MyBean : 3.初始化:实现InitializingBean接口或在XML中配置init-method属性 重写afterPropertiesSet方法
2023-04-04 15:51:39.687 INFO 44460 --- [ main] c.e.d.beanLifeTest.MyBeanPostProcessor : 3-Initialization-After 初始化后回调方法:实现BeanPostProcessor接口的postProcessAfterInitialization方法
2023-04-04 15:51:46.054 INFO 44460 --- [ main] com.example.demo.beanLifeTest.MyBean : 6.使用:在程序中使用Bean对象mary
2023-04-04 15:51:46.090 INFO 44460 --- [extShutdownHook] com.example.demo.beanLifeTest.MyBean : 7.销毁前回调方法:使用@PreDestroy注解
2023-04-04 15:51:46.090 INFO 44460 --- [extShutdownHook] com.example.demo.beanLifeTest.MyBean : 7.销毁前回调方法:实现DisposableBean接口