BeanDefinitionRegistryPostProcessor , BeanFactoryPostProcessor ,InstantiationAwareBeanPostProcessor, BeanPostProcessor是spring生命周期中常见的4个后置处理器,但是对于其作用和执行顺序很多人还不是非常清楚,这里给大家讲解一下其作用以及执行顺序,并带上实操。
生命周期图:
BeanDefinitionRegistryPostProcessor 是一个扩展了 BeanFactoryPostProcessor 的接口,它可以在 Spring 容器加载了所有的 bean 定义之后,但是在 bean 实例化之前,对 bean 的定义进行修改或者添加 。它的 postProcessBeanDefinitionRegistry 方法会在所有的 bean 定义被加载后,但是在任何 bean 实例化之前被调用。它的 postProcessBeanFactory 方法会在所有的 bean 实例化之后被调用。因此,它的执行顺序是最先执行 postProcessBeanDefinitionRegistry 方法,然后执行 postProcessBeanFactory 方法。
BeanFactoryPostProcessor 是一个可以在 Spring 容器加载了所有的 bean 定义之后,但是在 bean 实例化之前,对 bean 的定义进行修改或者添加的接口 。它的 postProcessBeanFactory 方法会在所有的 bean 定义被加载后,但是在任何 bean 实例化之前被调用。因此,它的执行顺序是在 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法之后,但是在 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法之前。
InstantiationAwareBeanPostProcessor 是一个扩展了 BeanPostProcessor 的接口,它可以在 Spring 容器实例化 bean 的过程中,对 bean 进行修改或者增强。它有四个方法:postProcessBeforeInstantiation、postProcessAfterInstantiation、postProcessPropertyValues 和 postProcessBeforeInitialization。它的执行顺序是:
BeanPostProcessor 是一个可以在 Spring 容器实例化和初始化 bean 的过程中,对 bean 进行修改或者增强的接口 。它有两个方法:postProcessBeforeInitialization 和 postProcessAfterInitialization。它的执行顺序是:
在每个 bean 初始化之前,调用 postProcessBeforeInitialization 方法,如果该方法返回非空对象,则使用返回的对象作为初始化结果。
在每个 bean 初始化之后,调用 postProcessAfterInitialization 方法,如果该方法返回非空对象,则使用返回的对象作为最终结果。
总结一下,这几个接口的执行顺序和作用如下:
PostProcessor 类型 | 处理目标 | 执行时机 | 可操作的空间 |
---|---|---|---|
BeanDefinitionRegistryPostProcessor | BeanDefinition、.class 文件等 | 配置文件、配置类已解析完毕并注册进 BeanFactory,但还没有被 BeanFactoryPostProcessor 处理 | 向 BeanFactory 中注册新的 BeanDefinition |
BeanFactoryPostProcessor | BeanDefinition | BeanDefinition 解析完毕并注册进 BeanFactory 之后(此时 bean 未实例化) | 给 BeanDefinition 中增删属性、移除 BeanDefinition 等 |
InstantiationAwareBeanPostProcessor | bean 实例 | bean 的实例化阶段前后(在实例化 bean 对象之前和之后) | 在 bean 实例化的过程中,可以对实例化的 bean 进行定制化的操作,例如自定义实例化逻辑、修改实例化后的属性值等 |
BeanPostProcessor | bean 实例 | bean 的初始化阶段前后(已创建出 bean 对象) | 给 bean 的属性赋值、创建代理对象等 |
首先,我们需要创建一个 Spring Boot 项目,并在 pom.xml 中添加以下依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
然后,我们需要定义以下四个后置处理器的实现类,并使用 @Component 注解标注它们,以便让 Spring 自动扫描并注册它们:
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry");
// 创建一个新的 bean 定义
BeanDefinition beanDefinition = new RootBeanDefinition(MyNewBean.class);
// 注册到容器中
registry.registerBeanDefinition("myNewBean", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory");
// 修改已有的 bean 定义
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("helloService");
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
}
}
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor.postProcessBeanFactory");
// 修改已有的 bean 定义
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("worldService");
beanDefinition.setLazyInit(true);
}
}
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation: " + beanName);
// 如果返回非空对象,则跳过后续的实例化过程
if (beanName.equals("myNewBean")) {
return new MyNewBean("Created by postProcessBeforeInstantiation");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation: " + beanName);
// 如果返回 false,则跳过后续的属性注入过程
if (beanName.equals("helloService")) {
return false;
}
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues: " + beanName);
// 如果返回非空属性值,则使用返回的属性值进行注入
if (beanName.equals("worldService")) {
return new MutablePropertyValues().add("message", "Modified by postProcessPropertyValues");
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization: " + beanName);
// 如果返回非空对象,则使用返回的对象作为初始化结果
if (beanName.equals("myNewBean")) {
return new MyNewBean("Modified by postProcessBeforeInitialization");
}
return bean;
}
}
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization: " + beanName);
// 如果返回非空对象,则使用返回的对象作为初始化结果
if (beanName.equals("helloService")) {
return new HelloService("Modified by postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBeanPostProcessor.postProcessAfterInitialization: " + beanName);
// 如果返回非空对象,则使用返回的对象作为最终结果
if (beanName.equals("worldService")) {
return new WorldService("Modified by postProcessAfterInitialization");
}
return bean;
}
}
接下来,我们需要定义以下四个普通的 bean 类,并使用 @Component 或者 @Service 注解标注它们,以便让 Spring 自动扫描并注册它们:
@Service
public class HelloService {
private String message;
public HelloService() {
this.message = "Hello, Spring!";
}
public HelloService(String message) {
this.message = message;
}
public void sayHello() {
System.out.println(message);
}
}
@Service
public class WorldService {
private String message;
public WorldService() {
this.message = "World, Spring!";
}
public WorldService(String message) {
this.message = message;
}
public void sayWorld() {
System.out.println(message);
}
}
public class MyNewBean {
private String message;
public MyNewBean() {
this.message = "This is a new bean!";
}
public MyNewBean(String message) {
this.message = message;
}
public void saySomething() {
System.out.println(message);
}
}
@RestController
public class TestController {
@Autowired
private HelloService helloService;
@Autowired
private WorldService worldService;
@Autowired
private MyNewBean myNewBean;
@GetMapping("/test")
public String test() {
helloService.sayHello();
worldService.sayWorld();
myNewBean.saySomething();
return "Test done!";
}
}
最后,我们可以运行 Spring Boot 项目,并访问 http://localhost:8080/test ,观察控制台的输出,以及各个后置处理器的执行顺序和作用。我们可以看到以下结果:
MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
MyBeanFactoryPostProcessor.postProcessBeanFactory
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation: helloService
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation: worldService
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation: worldService
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues: worldService
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization: worldService
MyBeanPostProcessor.postProcessBeforeInitialization: worldService
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization: worldService
MyBeanPostProcessor.postProcessAfterInitialization: worldService
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation: myNewBean
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization: myNewBean
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization: myNewBean
Modified by postProcessBeforeInitialization
Modified by postProcessPropertyValues and postProcessAfterInitialization
Modified by postProcessBeforeInitialization
Test done!
从上面的结果可以看出,这四个后置处理器的执行顺序和作用如下: