文章目录
BeanFactory的后置处理器
1. BeanFactory的后置处理器是什么?
首先,Spring容器在运行的过程中,第一步肯定是创建一个BeanFactory工厂对象,这个对象来负责bean的注册,bean的创建等一系列工作。一般默认的是org.springframework.beans.factory.support.DefaultListableBeanFactory 这个类。当然这部分工作是Spring来完成的,工厂初始化完之后,为了让用户可以去做一些定制型的事情,所以提供了org.springframework.beans.factory.config.BeanFactoryPostProcessor 函数式接口,使用过程中只需要实现这个接口,然后将当前的类注册进去即可。
2. BeanFactory的后置处理器分类
共分为两类:一个是带注册功能的后置处理器,即实现org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor接口。一个是不带注册功能的后置处理器,即实现org.springframework.beans.factory.config.BeanFactoryPostProcessor 接口。
ps: BeanDefinitionRegistryPostProcessor接口是继承了BeanFactoryPostProcessor 接口
3. BeanFactory的后置处理器使用
3.1 BeanDefinitionRegistryPostProcessor 带注册功能的
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 参数registry 是 BeanDefinitionRegistry 类型的。
// 其实真正传过来的是DefaultListableBeanFactory对象
if (registry instanceof DefaultListableBeanFactory){
System.out.println("true");
}
// 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 参数beanFactory 是 ConfigurableListableBeanFactory 类型的。
// 其实真正传过来的是DefaultListableBeanFactory对象
if (beanFactory instanceof DefaultListableBeanFactory){
System.out.println("----");
System.out.println("true");
}
// 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
}
}
两次传入过来的都是DefaultListableBeanFactory对象,为什么还要搞成两个方法?其实这里涉及一个调用顺序的问题,后面会讲。
3.2 BeanFactoryPostProcessor 不带注册功能的
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 参数beanFactory 是 ConfigurableListableBeanFactory 类型的。
// 其实真正传过来的是DefaultListableBeanFactory对象
if (beanFactory instanceof DefaultListableBeanFactory){
System.out.println("----");
System.out.println("true");
}
// 在这里,我们调用DefaultListableBeanFactory的任何API,做我们自己想做的事情。
}
}
用起来没什么难的。
4. BeanFactory的后置处理器IOC加载顺序。
既然需要去调用我们自己定义的BeanFactory的后置处理器,首先我们的BeanFactory的后置处理器肯定是先注册到Spring容器中,然后创建对应的对象来进行方法的调用。所以我们要搞清楚BeanFactory的后置处理器何时被注册?
在注解方式下: 首先会去加载Spring自带的BeanFactory的后置处理器,之后在解析配置类即带有@Configuration注解类的时候将自定义的BeanFactory的后置处理器注册进去,然后在调用。
4.1 Spring自带的BeanFactory的后置处理器。
在创建AnnotationConfigApplicationContext对象的时候,同时会去创建一个AnnotatedBeanDefinitionReader类,在AnnotatedBeanDefinitionReader类的构造过程中,会去注册Spring自带的BeanFactory的后置处理器。具体代码如下:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
其实只是注册了两个BeanFactory后置处理器。一个是 ConfigurationClassPostProcessor.class,一个是EventListenerMethodProcessor.class。主要关注的是ConfigurationClassPostProcessor.class,此BeanFactory的后置处理器是解析@Configuration来使用的。自定义的后置处理器,也是在解析@Configuration后来实现注册。当然你可以手动强制性注册,野路子。
4.2 自定义的BeanFactory的后置处理器。
自定义的BeanFactory的后置处理器,正常情况是,是在解析了@Configuration后来进行注册,也就是Spring自带的ConfigurationClassPostProcessor.class执行完,自定义的就会注册完。当然你可以手动调用register方法进行注册。例如:
5. BeanFactory的后置处理器执行顺序,重点。
上面讲过了BeanFactory的后置处理器的注册,现在看一下BeanFactory的后置处理器的执行阶段,当然涉及到一个执行的顺序问题。
BeanFactory的后置处理器执行调用的方法在 refresh 方法中。
点进去看一下
具体代码实现如下:
// 此方法进行beanFactory的后置处理器调用,参数beanFactory是之前创建好的DefaultListableBeanFactory对象,参数beanFactoryPostProcessors,是beanFactory后置处理器对象的集合,但是这个时候是空的。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 创建一个处理器bean的set集合。
Set<String> processedBeans = new HashSet<>();
// 此时BeanDefinitionRegistry的null,所以此方法不会走,考虑的其他的情况,所以有这段代码。
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 创建一个list集合,后续用于存放已经实例化的beanFactory后置处理器。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先去调用,实现了BeanDefinitionRegistryPostProcessors接口的后置处理器。并且实现了PriorityOrdered接口的。此处获取对应的对象名称。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环判断,找出实现PriorityOrdered接口的beanFactory的后置处理器,调用优先级最高。
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 如果已经实现了,调用getBean去创建对象。Spring自己也会去调用getBean对象,不只是我们会去调用。并且放入到马上被调用的beanFactory的后置处理器中。
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 放入到所有的后置处理器中。
processedBeans.add(ppName);
}
}
// 进行排序,因为实现PriorityOrdered.class接口的也可以有很多个,可以根据值来设置调用的优先顺序。
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 把将要调用的beanFactory的后置处理去放入到registryProcessors中。
registryProcessors.addAll(currentRegistryProcessors);
// 这里开始真正的调用beanFactory的后置处理器。
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 已经被调用后清除currentRegistryProcessors集合。
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 再次获取一次beanFactory的后置处理器名单。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环调用
for (String ppName : postProcessorNames) {
// 先判断是否已经被调用过,然后调用实现Ordered接口的beanFactory的后置处理器
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 依然是去创建实现了Ordered接口的beanFactory的后置处理器对象。
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 加入到processedBeans集合中
processedBeans.add(ppName);
}
}
// 仍然进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 放入到registryProcessors集合中
registryProcessors.addAll(currentRegistryProcessors);
// 调用实现了Odered接口的beanFactory后置处理器
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清除currentRegistryProcessors集合。
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 调用剩下的没有实现Ordered 和PriorityOrdered 接口的beanFactory的后置处理器。
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 获取所有的实现了BeanDefinitionRegistryPostProcessor接口的bean的后置处理器。
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 循环判断
for (String ppName : postProcessorNames) {
// 是否已经被调用过,如果没有被调用,就会被调用。
if (!processedBeans.contains(ppName)) {
// 创建bean对象,添加到这个集合中currentRegistryProcessors
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
// 进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到registryProcessors集合中
registryProcessors.addAll(currentRegistryProcessors);
// 开始调用。具体的可以看下面。
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清除集合。
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 因为BeanDefinitionRegistryPostProcessor接口是继承BeanFactoryPostProcessor接口的,所以我们之前只是调用了postProcessBeanDefinitionRegistry方法,还有一个postProcessBeanFactory没有调用。在此处调用。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 这个没什么意义。
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
// 此处用于其他工程对象进行调用的。
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 获取所有实现BeanFactoryPostProcessor接口的beanFactory后置处理器。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 创建三个集合,priorityOrderedPostProcessors 存放实现了priorityOrdered接口的,
// orderedPostProcessorNames 存放实现了ordered接口的。
// nonOrderedPostProcessorNames 没有实现任何排序接口的。
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 循环遍历
for (String ppName : postProcessorNames) {
// 出去上一个阶段调用过的。
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
// 找出实现了PriorityOrdered接口的。
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 并且此时已经创建好bean了。
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// 找出实现了Ordered接口的。
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
// 找出没有实现排序接口的。
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 最先调用实现了priorityOrdered接口的,进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 进行调用
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 然后调用实现了ordered接口的。
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
// 创建了实现ordered接口的实例。
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 调用
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 最后调用没有实现排序接口的
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 创建实例
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 进行调用。
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 清楚缓存, 因为beanFactory的后置处理器可能已经修改了bean的信息。
beanFactory.clearMetadataCache();
}
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
// 调用实现了BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法。
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
图解:
5. BeanFactory的后置处理器执行顺序扩展点
5.1 扩展点1 排序接口
排序接口有两种,一种是 PriorityOrdered接口,一种是Ordered接口。
由此可知,PriorityOrdered继承了Ordered类,而且实现PriorityOrdered接口的执行顺序在实现了Ordered接口之前。
5.2 PriorityOrdered 排序接口 对自定义beanFactory的后置处理器的意义
1.如果自定义BeanFactory的后置处理器,正常逻辑是在ConigurationClassPostProcessor的执行后才加载,所以一定程度上PriorityOrdered对自定义beanFactory的后置处理器没任何意义。
2.但是我们可以强行把自定义beanFactory的后置处理器的执行顺序提到ConigurationClassPostProcessor之前。具体操作:
- 实现 PriorityOrdered接口。并且getOrder(),可以控制顺序,但是ConigurationClassPostProcessor永远是最优先的。
- 手动注册自定义BeanFactory的后置处理器。