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因为默认扫描启动类的包,就不会扫描到PersonCat,直接启动的话预计是会报错的,试验下
在这里插入图片描述

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();
	}

由此可以总结出来调用的顺序
BeanDefinitionRegistryPostProcessorPriorityOrdered的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessorOrdered的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry的方法
BeanDefinitionRegistryPostProcessorPriorityOrdered的postProcessBeanFactory的方法
BeanDefinitionRegistryPostProcessorOrdered的postProcessBeanFactory的方法
BeanDefinitionRegistryPostProcessor的postProcessBeanFactory的方法
BeanFactoryPostProcessorPriorityOrdered的postProcessBeanFactory的方法
BeanFactoryPostProcessorOrdered的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));
	}

总结下注册顺序
BeanPostProcessorPriorityOrdered的类
BeanPostProcessorOrdered的类
BeanPostProcessor的类
这些方法在实例化bean的时候都会被调用到的

对于后置处理的总结大部分都结束了,留下了些小坑,比如BeanPostProcessor的子类何时会被调用之类的,详情请看下回分析,总体上来说,本派篇的源码还是很简单的,主要是应用的部分,另外就是这种spring的拓展的思想,这种模式,是需要我们去思考借鉴与学习的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值