前言
在读源码是必能看见BeanPostProcessor相关语句,这里收集记录下这个接口的作用和使用。
这个扩展点是发生在bean实例化之前,BeanDefinition读取完之后。所以我们在这里可以获取到BeanDefinition,以改变他默认的实例化方式。
接口分析
可以看见这个接口很简单,只有1个方法约束。
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
:在标准初始化之后,修改应用程序上下文的内部Bean工厂。此时所有的Bean定义都已被加载,但还没有Bean被实例化。这允许重写或添加属性,即使是急于初始化的Bean。
使用
基础准备
准备一个Person对象
package wang.wenlei.service.impl.test;
import lombok.Data;
@Data
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public Person(){}
}
准备一个
package wang.wenlei.service.impl.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===>调用BeanFactoryPostProcessor开始");
//获取到Spring中所有的beanName
String[] beanStr = beanFactory.getBeanDefinitionNames();
//循环bean做出自定义的操作
for (String beanName : beanStr) {
System.out.println("-->bean name:"+beanName);
if ("person".equals(beanName)) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
System.out.println("修改person的name值");
beanDefinition.getPropertyValues().add("name", "wwl2");
}
}
System.out.println("===>调用BeanFactoryPostProcessor结束");
}
}
Spring使用
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
Object person = applicationContext.getBean("person");
System.out.println(person);
}
执行效果:
可以看到会循环所有注册的Bean名称并打印出来,处理了代码中判断的person
并进行处理赋值为wwl2
看下不带这个后置处理器执行的结果做一下对比
SpringBoot使用
直接在MyBeanFactoryPostProcessor
上加一个@Component
注解。效果一样,就是打印有点多,不在这里截图了。
为什么把MeBeanPostProcessor上加一个@Component注解就能让BeanFactoryPostProcessor生效?
refresh方法会调用 registerBeanPostProcessors()方法。这个方法会将检测到的 BeanPostProcessor 注入到SpringBoot容器AnnotationConfigApplicationContext中。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 省略一大部分代码
// 调用工厂处理注册Bean到上下文
invokeBeanFactoryPostProcessors(beanFactory);
}
// 省略
}
1.判断beanFactory是否继承了BeanDefinitionRegistry类
2.获取BeanDefinitionRegistryPostProcessor的集合
3.将集合的后置器分类,然后各自分顺序执行。
完~
求指导、关注、点赞