Spring Bean的生命周期
Bean的生命周期
1. 初始化Bean
容器通过获取BeanDefinition中的信息进行实例化,这一步仅仅是简单的实例化,并没有进行依赖注入。
实例化的对象被包装在BeanWrapper对象中,BeanWrapper提供了设置对象属性的接口,从而避免了使用反射机制来注入属性。
2. 设置对象属性(依赖注入)
实例化后的Bean仍是一个原生的状态,然后Spring根据BeanDefinition中的信息进行依赖注入,并且通过BeanWrapper提供的设置属性的接口完成依赖注入。
3. 注入Aware接口
Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。
BeanNameAware:通过Bean的引用来获取Bean的ID,一般业务中很少使用;BeanFactoryAware:获取Spring BeanFactory容器,如发布事件等;ApplicationContextAwaer:获取Spring ApplicationContext容器;
4. BeanPostProcessor前置处理
如果Spring实现了BeanPostProcessor接口,pring将调用它们的postProcessBeforeInitialization(Object bean, String beanName)(预初始化)方法,作用是在Bean实例创建成功后对进行增强处理,如对Bean进行修改,增加某个功能。
5. InitializingBean接口
InitializingBean接口只有一个函数:afterPropertiesSet(),作用是在bean正式构造完成前增加我们自己自定义的逻辑,与前置处理不同,该函数的入参没有bean对象, 因为无法处理bean对象本身,只能增加一些额外的逻辑。
6. init-method声明
作用同InitializingBean接口。
7. BeanPostProcessor后置处理
如果Spring实现了BeanPostProcessor接口,pring将调用它们的postProcessAfterInitialization(Object bean, String beanName)(预初始化)方法,作用与4的一样,只不过6是在Bean初始化前执行的,而这个是在Bean初始化后执行的,时机不同。
8. Bean初始化完成
经过以上的工作后,Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁。
9. DispostbleBean接口
DispostbleBean接口只有一个函数:destroy(),在bean被销毁前执行此函数里的逻辑。
10. destroy-method声明
作用同DispostbleBean接口。
代码
person类实现了BeanNameAware、 BeanFactoryAware、 ApplicationContextAwaer、 InitializingBean、 DispostbleBean 接口。
package tech.mervyn.demo.entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Person implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
private String name;
public Person() {
System.out.println("调用默认构造器实例化对象...");
}
public void setName(String name) {
System.out.println("调用Setter方法设置属性...");
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
@Override
public void setBeanName(String name) {
System.out.println("获取beanName -> " + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("获取BeanFactory -> " + beanFactory.hashCode());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("获取applicationContext -> " + applicationContext.hashCode());
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("执行InitializingBean逻辑...");
}
public void initMethod() {
System.out.println("执行init-method声明逻辑...");
}
@Override
public void destroy() throws Exception {
System.out.println("执行DisposableBean逻辑...");
}
public void destroyMethod() {
System.out.println("执行destroy-method声明逻辑...");
}
}
自定义MyBeanPostProcessor类继承BeanPostProcessor并实现postProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName)方法。
package tech.mervyn.demo.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor前置处理," + beanName + " -> " + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor后置处理," + beanName + " -> " + bean);
return bean;
}
}
配置类
package tech.mervyn.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.mervyn.demo.entity.Person;
import tech.mervyn.demo.processor.MyBeanPostProcessor;
@Configuration
public class AppConfig {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public Person person() {
Person person = new Person();
person.setName("Mervyn");
return person;
}
@Bean
public MyBeanPostProcessor myBeanPostProcessor() {
return new MyBeanPostProcessor();
}
}
执行
package tech.mervyn.demo;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import tech.mervyn.demo.config.AppConfig;
public class LiftCycleTests {
@Test
void liftCycle() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
context.registerShutdownHook();
}
}
输出,其中删除了一些无用日志:
22:29:54.047 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'appConfig'
22:29:54.052 [main] INFO org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'appConfig' of type [tech.mervyn.demo.config.AppConfig$$EnhancerBySpringCGLIB$$b60c41a9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
22:29:54.072 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'
调用默认构造器实例化对象...
调用Setter方法设置属性...
获取beanName -> person
获取BeanFactory -> 1390913202
获取applicationContext -> 1297836716
BeanPostProcessor前置处理,person -> Person{name='Mervyn'}
执行InitializingBean逻辑...
执行init-method声明逻辑...
BeanPostProcessor后置处理,person -> Person{name='Mervyn'}
执行DisposableBean逻辑...
执行destroy-method声明逻辑...
注意,日志中有这样一行输出:
org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'appConfig' of type [tech.mervyn.demo.config.AppConfig$$EnhancerBySpringCGLIB$$b60c41a9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying),打印这行信息是由于BeanPostProcessor启动时对依赖的Bean造成误伤,具体原因有时间再讲。