赵云胡说--spring的后置处理
序
spring的xml配置和注解解析为BeanDefinition的过程已经差不多分析完毕了,沿着首篇的主线路,来到了后置处理器了,其实在之前的博客中提到了很多关于后置处理器的调用,本篇将详细追踪源码如何调用这些后置处理类的
后置处理的接口
BeanPostProcessor
BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor
这三位是长的很像的都是以Bean开头,PostProcessor结尾的.翻译一下分别就是:
Bean的后置处理器
BeanFactory的后置处理器
BeanDefinitionRegistry的后置处理器
感觉自己在翻译的像个傻子…,不过确实就是这样子的,看下这些接口的样子:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
BeanPostProcessor:就是对实例化好的Bean进行一些操作的,它的两个接口方法,入参中都是有Bean对象,以及bean名称的
BeanFactoryPostProcessor:看入参是ConfigurableListableBeanFactory就知道,这个接口可以让我们去自己操作BeanFactory的
BeanDefinitionRegistryPostProcessor: 同样看入参BeanDefinitionRegistry,这是对BeanDefinition进行的操作的接口了,同时这个接口也继承了BeanFactoryPostProcessor接口
接口的实践测试
首先写上测试主类,为了方便,使用了注解方法启动
@ComponentScan
public class SevenStart {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SevenStart.class);
System.out.println(context.getBean(Person.class));
System.out.println(context.getBean(Cat.class));
}
}
Person
@Component
public class Person {
private String name;
private Dog dog;
private Integer age;
public String getName() {
return name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}```
Cat
```java
@Component
public class Cat {
private String colore;
private String sex;
private String name;
private Dog dog;
public String getColore() {
return colore;
}
public void setColore(String colore) {
this.colore = colore;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Cat{" +
"colore='" + colore + '\'' +
", sex='" + sex + '\'' +
", name='" + name + '\'' +
", dog=" + dog +
'}';
}
}
Dog
@PropertySource("classpath:a.properties")
public class Dog{
private String colore;
private String sex;
@Value("${aa}")
private String name;
private Cat cat;
public Cat cat(){
return cat;
}
public String getColore() {
return colore;
}
public void setColore(String colore) {
this.colore = colore;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"colore='" + colore + '\'' +
", sex='" + sex + '\'' +
", name='" + name + '\'' +
", cat=" + cat +
'}';
}
}
其中Person类和Cat类和Dog,不在启动类的包下,这时候@ComponentScan因为默认扫描启动类的包,就不会扫描到Person和Cat,直接启动的话预计是会报错的,试验下
BeanDefinitionRestryPostProcessorDemo
果然报错了~.那么首先在SevenStart同一个包下加入BeanDefinitionRestryPostProcessorDemo类,如下:
@Component
public class BeanDefinitionRestryPostProcessorDemo implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
scanner.scan("com.zk.firstStudy");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
然后执行:
成功将Person类和Cat类扫描进来了,至于ClassPathBeanDefinitionScanner 在这了不赘述了,想要了解可以看这篇博客
BeanFactoryPostProcessorDemo
在这里将扫描的person类的类名偷换成Dog,运行主类启动
@Component
public class BeanFactoryPostProcessorDemo implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.getBeanDefinition("person").setBeanClassName("com.zk.firstStudy.Dog");
}
}
显示的是没有Person类
那么dog类有没有被扫描进去呢?我们把启动主类改一下,获取一个Dog, ** System.out.println(context.getBean(Dog.class));**
这时是能获取到的
不过如果你看过这篇博客,有没有想过,@PropertySource(“classpath:a.properties”)上面的配置文件为什么没有注入呢?
BeanPostProcessorDemo
再往启动主类下加上BeanPostProcessorDemo 这个类,试试看
@Component
public class BeanPostProcessorDemo implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("person")) {
Dog dog = (Dog) bean;
dog.setSex("男");
dog.setName("大黄");
dog.setColore("黄色");
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("person")) {
Dog dog = (Dog) bean;
dog.setColore("绿色");
}
return null;
}
}
我们继续运行
最后大黄由黄色变成绿色了,真是个可怜的人,从人变成狗,最后还被绿了
接口的源码追溯
//处理和执行BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
//注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet<>();
//..................省略................................
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//首先把BeanDefinitionRegistryPostProcessor的子类全部查出来
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//筛选后的类再看下有没有实现PriorityOrdered.class接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//在此实例化并加入集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//根据实现的PriorityOrdered.class接口排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//该方法循环Set去调用BeanDefinitionRegistryPostProcessors方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//再来一次筛选出来实现Ordered.class和BeanDefinitionRegistryPostProcessor的子类
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//在此实例化并加入集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//根据实现的Ordered接口排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//该方法循环Set去调用BeanDefinitionRegistryPostProcessors方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
//获取没有实现排序接口的BeanDefinitionRegistryPostProcessor子类在此实例化并加入集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//在此执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//筛选BeanFactoryPostProcessor的子类,之后的步骤跟上面一样也是排序相关
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
由此可以总结出来调用的顺序
BeanDefinitionRegistryPostProcessor和PriorityOrdered的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessor和Ordered的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessor和PriorityOrdered的postProcessBeanFactory的方法
BeanDefinitionRegistryPostProcessor和Ordered的postProcessBeanFactory的方法
BeanDefinitionRegistryPostProcessor的postProcessBeanFactory的方法
BeanFactoryPostProcessor和PriorityOrdered的postProcessBeanFactory的方法
BeanFactoryPostProcessor和Ordered的postProcessBeanFactory的方法
BeanFactoryPostProcessor的postProcessBeanFactory的方法
回答下之前的问题,因为ConfigClassPostProcessor是实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered的接口,所以对PropertySource注解已经解析完了,后面再怎么做也不会返回去执行ConfigClassPostProcessor中的解析方法了.
registerBeanPostProcessors();
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//找出所有BeanPostProcessor的子类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//PriorityOrdered排序
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//Ordered排序
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册进去
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
//没有Order接口的BeanPostProcessor
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
总结下注册顺序
BeanPostProcessor和PriorityOrdered的类
BeanPostProcessor和Ordered的类
BeanPostProcessor的类
这些方法在实例化bean的时候都会被调用到的
结
对于后置处理的总结大部分都结束了,留下了些小坑,比如BeanPostProcessor的子类何时会被调用之类的,详情请看下回分析,总体上来说,本派篇的源码还是很简单的,主要是应用的部分,另外就是这种spring的拓展的思想,这种模式,是需要我们去思考借鉴与学习的