【spring源码】五、工厂后置处理器BeanFactoryPostProcessor【重要】


说明,本来参考了子路老师博客https://blog.csdn.net/java_lyvee/category_7351027.html,但自己也看过很多这方面的视频,包括尚硅谷的注解驱动开发,所以加了些自己的说明,尽量简洁。个人认为此文是我近期写的最好的一篇了,我感觉快要打通ssm源码整合了。

按理说工厂后置处理器没有getBean重点,但是我读了那么久源码迟迟有些地方不懂,就是因为当初没有读好工厂的后置处理器,一直没有搞懂注解的注册时机,再加上尚硅谷讲的@EnableAspectJAutoProxy也没说好到底怎么个注册法,看了几遍才发现是工厂后置处理器的问题。故写了此文

正在更新spring源码系统文章:

一、工厂后置处理器基础知识

工厂后置处理器的作用是新增和修改bean定义的,而spring中有两个接口与工厂后置处理器有关,分别是BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor

  • BeanFactoryPostProcessor:需要实现一个方法。只能修改bean定义
  • BeanDefinitionRegistryPostProcessor:他本身有一个需要实现方法,但因为继承了BeanFactoryPostProcessor接口,所以需要实现2个方法。分别是修改和添加bean定义

在实际开发中用的比较少,但各个框架源码整合中用的比较多,这里我们就不写用法了,直接看helloworld吧。

二、测试代码

bean定义:bean Definition,我们简称bd,存放bd的map我们简写为bd map,不懂bd的可以取前文看

1 工厂后置处理器

我们首先需要了解他们的用法,如下,我分别为每个接口创建了个实现类,只做了简单打印,用来看看他当时里面有什么bean定义,并用注解@Component将他们加到spring容器中。

1.1 注解的:
@Component
public class MyFacPostProcess_zhujie implements BeanFactoryPostProcessor {
    
    
	@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
		System.out.println("===注解的MyFacPostProcess.postProcessBeanFactory()被执行。。。");
		int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
		String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}
}
@Component
public class MyBeanDefinitionRegistryPostProcessor_zhujie implements BeanDefinitionRegistryPostProcessor {
    
    
	@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
		System.out.println("===注解的MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()执行。。。");
		int count = registry.getBeanDefinitionCount();//bean定义的数量
		String[] names = registry.getBeanDefinitionNames();//bean定义的名字
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));

		GenericBeanDefinition genericBeanDefinition =
			new GenericBeanDefinition() ;
		genericBeanDefinition.setBeanClass(Yellow.class);
		registry.registerBeanDefinition("yellow1",genericBeanDefinition);

	}

	@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
		System.out.println("===注解的MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory()执行。。。");
		int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
		String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}
}
1.2 通过ac.addBeanFactoryPostProcessor添加的实体bean

注意不要加@Component注解,我们要手动注册工厂后置处理器。而且我们传入ac的时候已经是实例化好的

public class RuCanBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    
	@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
		System.out.println("===入参的registry.postProcessBeanDefinitionRegistry()执行。。。");
	}

	@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
		System.out.println("===入参的registry.postProcessBeanDefinitionRegistry()执行。。。");
	}
}
public class RuCanBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    

	@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
		System.out.println("===入参的普通factoryPostPro.postProcessBeanDefinitionRegistry()执行。。。");
	}
}
1.3 通过ac.registerBeanDefinition添加的bd

(下面这两个类不用太在意,其实是我前期没学好弄的,但加上也无所谓,我们就能判断ac.addBeanFactoryPostProcessor和ac.registerBeanDefinition的区别了)

public class MyFacPostProcess_ShouDongZhuRu implements BeanFactoryPostProcessor{
    
    

    @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("===手动注入的MyFacPostProcess.postProcessBeanFactory()被执行。。。");
        int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
        String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
        System.out.println("当前BeanFactory中有"+count+" 个Bean");
        System.out.println(Arrays.asList(names));
    }
}
public class MyBeanDefinitionRegistryPostProcessor_ShouDongZhuRu implements BeanDefinitionRegistryPostProcessor{
    
    

    @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("===手动注入的MyBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()执行。。。");
        int count = registry.getBeanDefinitionCount();//bean定义的数量
        String[] names = registry.getBeanDefinitionNames();//bean定义的名字
        System.out.println("当前BeanFactory中有"+count+" 个Bean");
        System.out.println(Arrays.asList(names));
        GenericBeanDefinition genericBeanDefinition =
            new GenericBeanDefinition() ;
        genericBeanDefinition.setBeanClass(Blue.class);
        registry.registerBeanDefinition("bule1",genericBeanDefinition);
    }

    @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("===手动注入的MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory()执行。。。");
        int count = beanFactory.getBeanDefinitionCount();//bean定义的数量
        String[] names = beanFactory.getBeanDefinitionNames();//bean定义的名字
        System.out.println("当前BeanFactory中有"+count+" 个Bean");
        System.out.println(Arrays.asList(names));
    }

}

2 配置类

@Configuration // 告诉Spring这是一个配置类
@ComponentScan(value="com.atguigu")
public class MainConfigFacPostProcesser {
    
    

	// 简单注入一个bean,观察执行时机
	@Bean
	Car Car1(){
    
    
		return new Car();
	}
}

3 启动类的改写

我们的启动类一般的写法是new AnnotationConfigApplicationContext(Config.class)这样子,但我们看一下他源码

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    
    
    this();
    register(componentClasses);
    refresh();
}

他分为了三个步骤,为了后续解释的需要,我们给他们分开写。另外我们应该意识到,在下面加注释就是在上面加注释,执行时机都是一样的。我们加了6个关键点,为了观察工厂的状态

public class MainTest1 {
    
    

	public static void main(String[] args) {
    
    
		// 1 去初始化工厂
		// 打断点。下面这句就是创建了一个空工厂
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();

		// 2 debug执行完上句发现bd map中有5个:
		// annotation.internalConfigurationAnnotationProcessor,实现了BeanDefinitionRegistryPostProcessor
		// annotation.internalAutowiredAnnotationProcessor,实现了BeanPostProcessor
		// annotation.internalCommonAnnotationProcessor,实现了BeanPostProcessor
		// event.internalEventListenerProcessor,实现了BeanFactoryPostProcessor
		// event.internalEventListenerFactory,实现了EventListenerFactory


		// 注册bean定义,而不是注册bean
		GenericBeanDefinition mygenericBD_BDRegistry_shoudongZhuCe = new GenericBeanDefinition();
		mygenericBD_BDRegistry_shoudongZhuCe.setBeanClass(MyBeanDefinitionRegistryPostProcessor_ShouDongZhuRu.class);

		GenericBeanDefinition mygenericBD_FacPostPro_shoudongZhuCe = new GenericBeanDefinition();
		mygenericBD_FacPostPro_shoudongZhuCe.setBeanClass(MyFacPostProcess_ShouDongZhuRu.class);

		ac.registerBeanDefinition("mygenericBD_BDRegistry_shoudongZhuCe",mygenericBD_BDRegistry_shoudongZhuCe);
		// 3 刚执行完上句,还没执行下局,bd map中bd个数由5变为6.此时还没有实例化bean
		ac.registerBeanDefinition("mygenericBD_FacPostPro_shoudongZhuCe",mygenericBD_FacPostPro_shoudongZhuCe);

		// 4 bd个数变为7
		ac.register(MainConfigFacPostProcesser.class);
		
		// 下面4行并不往bd map中添加,而是直接添加到了工厂中
		RuCanBeanDefinitionRegistryPostProcessor ruCanBeanDefinitionRegistryPostProcessor =
			new RuCanBeanDefinitionRegistryPostProcessor();
		RuCanBeanFactoryPostProcessor ruCanBeanFactoryPostProcessor = new RuCanBeanFactoryPostProcessor();
		ac.addBeanFactoryPostProcessor(ruCanBeanDefinitionRegistryPostProcessor);// 注意不要使用registerBean,得使用addBeanFactoryPostProcessor
		ac.addBeanFactoryPostProcessor(ruCanBeanFactoryPostProcessor);
		
		// 5 bd个数变为8
		// 打断点  初始化容器
		ac.refresh();
		// 6
		System.out.println(1);

	}
}

三、观察bd map变化

为了清晰,还改了下IDEA主题。。。

image-20201222170215341

如上所示,spring中工厂什么都没做时,内置的是5个bd

image-20201222170739578

如图,扫描完我们的一个bd后,工厂中bd新增至6个,后面再扫描一个我们的,就变为7个

image-20201222171031122

注意我们通过ac.addBeanFactoryPostProcessor注册的工厂后置处理器并不在bd map中

执行完refresh。。。那bean就更多了。。。

四、观察工厂后置处理器的执行时机

我们把手动注册的和注解注册的重写的每个工厂后置处理器的每个方法都打上断点,先观察一遍他们的执行顺序,我debug得到的顺序如下:

  • 先执行DefinitionRegistryPostProcessor.新增bd定义方法
    • 入参的一个方法RuCanBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
    • 内置类的一个方法ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
    • 手动注册bd的一个方法mygenericBD_BDRegistry_shoudongZhuCe.postProcessBeanDefinitionRegistry()
    • 有注解的一个方法MyBeanDefinitionRegistryPostProcessor_zhujie.postProcessBeanDefinitionRegistry
  • 后执行DefinitionRegistryPostProcessor.修改bd定义方法
    • 入参的第二个方法RuCanBeanDefinitionRegistryPostProcessor.postProcessBeanFactory
    • 内置类的第二个方法ConfigurationClassPostProcessor.postProcessBeanFactory
    • 手动注册bd的第二个方法mygenericBD_BDRegistry_shoudongZhuCe.postProcessBeanFactory
    • 注解的第二个方法MyBeanDefinitionRegistryPostProcessor_zhujie.postProcessBeanFactory
  • 最后执行普通工厂后置处理器.修改bd定义方法
    • 入参的.RuCanBeanFactoryPostProcessor.postProcessBeanFactory
    • 手动注册的MyFacPostProcess_ShouDongZhuRu.postProcessBeanFactory
    • 扫描注册的MyFacPostProcess_zhujie.postProcessBeanFactory()

总结优先级:

  • DefinitionRegistryPostProcessor>BeanFactoryPostProcessor。不管是哪里来的
  • DefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry>DefinitionRegistryPostProcessor.postProcessBeanFactory
  • 结合前两者就是
    • DefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry>
    • DefinitionRegistryPostProcessor.postProcessBeanFactory>
    • BeanFactoryPostProcessor.postProcessBeanFactory
  • 入参>内置>手动注册>注解

五、ConfigurationClassPostProcessor初识

先说下调用栈:

  • refresh()
  • invokeBeanFactoryPostProcessors()
  • PostProcessorRegisterDelegate.invokeBeanFacoryPostProcessors()

在这里插入图片描述

再说下bd(bean definition)是一步步加载出来的,并不是一下就都拿到bd了。而工厂后置处理器的工作就是实例化工厂后置处理器的同时加载bd。容器已经发现的bd放到了bd map中

先看下这个图

在这里插入图片描述

图源自子路老师:https://blog.csdn.net/java_lyvee/article/details/102633067

他的意思是说:bd会在ac容器启动时,也就是我们调用栈中invokeBeanFacoryPostProcessors去执行ConfigurationClassPostProcessor这个工厂后置处理器(实现了BeanDefinitionRegistryPostProcessor)的postProcessBeanDefinitionRegistry去完成bd的扫描,所以你去找到这个类的2个方法,也打上断点吧。现在我们就有了若干个工厂后置处理器实现方法的断点,我上面第四部分已经给出顺序:

好好品味一下,总结一下他们3个的优先级

再由下图看看ConfigurationClassPostProcessor的重要性

image-20201222213136647

六、debug工厂后置处理器

不管是什么工厂后置处理器都分为3个等级,实现PriorityOrdered接口的>实现Ordered接口的,没有实现优先级接口的。而且不只是工厂后置处理器,就连普通bean都会按照这个逻辑走。

还记得上面的执行逻辑吗?我在这里多说一句,实例化的时候不仅会实例化工厂中的后置处理器,而且同期传入方法的参数不只有工厂,还有另外一个参数,他也是工厂后置处理器。他的优先级是比factory中其他工厂后置处理器优先级高的,他在所有BDregistry类型的工厂后置处理器执行完2个方法后,立马执行入参的工厂后置处理器,所以说他的优先级高。另外,因为我们已经执行完了该入参,那么就没必要记录他是否没执行过了,因为肯定执行过了。

再说明一下,factory中有三种bean:工厂后置处理器,后置处理器,普通bean。我们在实例化工厂后置处理器时是不实例化后2者的,也就是说我们把后置处理器和普通bean的bd扫描出来而已,只是new bd,不是new bean。new 工厂是后面的工作,new 普通bean更是最后的最后才做。

另外有几个map了解一下:

  • processedBeans集合:因为工厂后置处理器是分批实例化的,这个集合就记录了已经实例化过的工厂后置处理器
  • currentRegistryProcessors集合:现在正在处理的后置处理器bean,他会拿到bean定义先实例化【getBean】,再放到集合中,然后去调用该工厂后置处理器的方法。注意是工厂后置处理器这个bean
  • registryProcessors集合:保存所有已经实例化好的工厂后置处理器
// PostProcessorRegistrationDelegate;

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, // 正在创建的工厂
    List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    //这个参数进来时候都为空

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.  存储已经处理完成的BeanFactoryPostProcessor
    Set<String> processedBeans = new HashSet<String>();

    // 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
    // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此进入if
    if (beanFactory instanceof BeanDefinitionRegistry) {
    
    //如果这个工厂是bean定义注册工厂,那么这个工厂不仅作用于注册bean定义前后,还作用于bean定以后的工厂初始化前
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;//强转,registry是工厂
        // 初始化两个list,观察名字就可以知道作用
        // 实现BeanFactoryPostProcessor(那么实现BeanDefinitionRegistryPostProcessor的也在里面)
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();//存放普通的"工厂"后置处理器
        // 实现接口BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();//存放"bean定义工厂"后置处理器

        //2.这里一般不进入,但程序员在refresh前加了ac.addBeanFactoryPostProcessor()就进入了
        // 这里的意思是说,先执行入参beanFactoryPostProcessors的方法,他优先级最高了(但也得遵守方法优先级的问题)
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    
    
            // 2.1 如果这个工厂后置处理器是BeanDefinitionRegistryPostProcessor
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    
    
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 2.1.1 直接执行入参的postProcessBeanDefinitionRegistry()方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 2.1.2 添加到registryProcessors-list(用于最后执行postProcessBeanFactory方法)
                registryProcessors.add(registryProcessor);
            }
            else {
    
    //入参只是普通的BeanFactoryPostProcessor
                // 2.2 入参只是普通的BeanFactoryPostProcessor,先添加到regularPostProcessors,
                // 后面再执行postProcessBeanFactory方法,防止顺序乱了,比较registry肯定优先级高
                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<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();//临时变量,存放本次要执行的工厂后置处理器BeanDefinitionRegistryPostProcessor,往下看就明白了,在下一次使用前clear// 

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类。这里只是拿到spring内置的
        // 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的后置处理器Bean的beanName。
        // 这里只会拿到ConfigurationAnnotationProcessor,但是我们在main中手动注册了1个,所以拿到2个
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 3.2 遍历ConfigurationAnnotationProcessor和手动注册的registry的工厂后置处理器
        for (String ppName : postProcessorNames) {
    
    
            // 3.3 校验是否实现了PriorityOrdered接口,但是我们的手动注册工厂后置处理器没有实现这个,所以不进入
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
                //3.4 getBean用于实例化工厂后置处理器
                // 这里只会实例化ConfigurationAnnotationProcessor
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 3.5 记录好实例化好的工厂后置处理器
                processedBeans.add(ppName);
            }
        }
        // 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        // 3.7 注册后置处理器到registryProcessors(用于最后执行postProcessBeanFactory方法)
        registryProcessors.addAll(currentRegistryProcessors);
        // 3.8 ***遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry()方法。我们之前只是实例化了ConfigurationAnnotationProcessor对象,还没有调用该对象重写的方法呢,我们当然得调用他们的方法了。但是我们手动注入的还没实例化呢,当然不在这里调用。对于ConfigurationAnnotationProcessor,我们后面会说
        // 我们还把入参形成的registry也传进去,他也去执行postProcessBeanDefinitionRegistry()方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 好家伙,执行完上句之后,直接把我们注解的bd全扫描到了
        // 3.9 执行完毕后, 清空currentRegistryProcessors-list
        currentRegistryProcessors.clear();

        // 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类
        //(过程跟上面的步骤3基本一样,重复一遍而已,但我们代码中没有这种类型,跳过)
        // 值得注意的是因为Config...扫描了很多bd,所以我们得重写拿到现有bd
        // 还有注意虽然我们可能重复拿到工厂后置处理器,但因为有processedBeans的判断,可以免于重复执行
        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
    
    
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 同样附加传入了入参形成的registry
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
        // 也就是没有实现优先级接口的。我们的BDRegistry...类都是在这里执行,也没什么好说的,跳过
        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
    
    
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
    
    
                if (!processedBeans.contains(ppName)) {
    
    
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    // 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
                    // 因此这边将reiterate赋值为true, 代表需要再循环查找一次
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        //  上面只调用完了BDregistry...里的一个方法,他里面还有一个方法需要我们去执行
        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        // 6.***调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法。
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//MyBeanDefinitionRegistryPostProcessor.postProcessBeanFactory
        
        
        // 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        // 这里还得多说一句,注意是入参中传过来的的,不是工厂中的后置处理器
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
    
    
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    //--------------跳出if,,else...

    // 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,下面开始处理容器中的所有BeanFactoryPostProcessor
     8.找出所有实现BeanFactoryPostProcessor接口的类
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    // 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
    for (String ppName : postProcessorNames) {
    
    
        if (processedBeans.contains(ppName)) {
    
    //已经执行过了就跳过
            // skip - already processed in first phase above
        }
        // 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
         // 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
            orderedPostProcessorNames.add(ppName);
        }
        // 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
        else {
    
    
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
    // 9.1 对priorityOrderedPostProcessors排序
    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

     // 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
    
    
        // 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 10.2 对orderedPostProcessors排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // 11.调用所有剩下的BeanFactoryPostProcessor
    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
    
    
        // 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);//MyBeanFactoryPostProcessor.postProcessBeanFactory

    // 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
    // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

七、解读ConfigurationClassPostProcessor

在这里插入图片描述

不想看了。。。肯定是一堆扫描注解

1 postProcessBeanDefinitionRegistry

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    
    
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
    
    
        throw new IllegalStateException(
            "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
    
    
        throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);

    processConfigBeanDefinitions(registry);
}

2 postProcessBeanFactory

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    
    
    int factoryId = System.identityHashCode(beanFactory);
    if (this.factoriesPostProcessed.contains(factoryId)) {
    
    
        throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + beanFactory);
    }
    this.factoriesPostProcessed.add(factoryId);
    if (!this.registriesPostProcessed.contains(factoryId)) {
    
    
        // BeanDefinitionRegistryPostProcessor hook apparently not supported...
        // Simply call processConfigurationClasses lazily at this point then.
        processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
    }

    enhanceConfigurationClasses(beanFactory);
    beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
1.1 processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    
    
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    String[] candidateNames = registry.getBeanDefinitionNames();

    for (String beanName : candidateNames) {
    
    
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
    
    
            if (logger.isDebugEnabled()) {
    
    
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
    
    
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }

    // Return immediately if no @Configuration classes were found
    if (configCandidates.isEmpty()) {
    
    
        return;
    }

    // Sort by previously determined @Order value, if applicable
    configCandidates.sort((bd1, bd2) -> {
    
    
        int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
        int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
        return Integer.compare(i1, i2);
    });

    // Detect any custom bean name generation strategy supplied through the enclosing application context
    SingletonBeanRegistry sbr = null;
    if (registry instanceof SingletonBeanRegistry) {
    
    
        sbr = (SingletonBeanRegistry) registry;
        if (!this.localBeanNameGeneratorSet) {
    
    
            BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
            if (generator != null) {
    
    
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
            }
        }
    }

    if (this.environment == null) {
    
    
        this.environment = new StandardEnvironment();
    }

    // Parse each @Configuration class
    ConfigurationClassParser parser = new ConfigurationClassParser(
        this.metadataReaderFactory, this.problemReporter, this.environment,
        this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
    
    
        parser.parse(candidates);
        parser.validate();

        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // Read the model and create bean definitions based on its content
        if (this.reader == null) {
    
    
            this.reader = new ConfigurationClassBeanDefinitionReader(
                registry, this.sourceExtractor, this.resourceLoader, this.environment,
                this.importBeanNameGenerator, parser.getImportRegistry());
        }
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);

        candidates.clear();
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
    
    
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
            Set<String> alreadyParsedClasses = new HashSet<>();
            for (ConfigurationClass configurationClass : alreadyParsed) {
    
    
                alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
            }
            for (String candidateName : newCandidateNames) {
    
    
                if (!oldCandidateNames.contains(candidateName)) {
    
    
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                        !alreadyParsedClasses.contains(bd.getBeanClassName())) {
    
    
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    while (!candidates.isEmpty());

    // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
    if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
    
    
        sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
    }

    if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
    
    
        // Clear cache in externally provided MetadataReaderFactory; this is a no-op
        // for a shared cache since it'll be cleared by the ApplicationContext.
        ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    }
}
2.1 enhanceConfigurationClasses
/**
	 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
	 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
	 * Candidate status is determined by BeanDefinition attribute metadata.
	 * @see ConfigurationClassEnhancer
	 */
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    
    
    Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
    
    
        BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
        Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
        MethodMetadata methodMetadata = null;
        if (beanDef instanceof AnnotatedBeanDefinition) {
    
    
            methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
        }
        if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
    
    
            // Configuration class (full or lite) or a configuration-derived @Bean method
            // -> resolve bean class at this point...
            AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
            if (!abd.hasBeanClass()) {
    
    
                try {
    
    
                    abd.resolveBeanClass(this.beanClassLoader);
                }
                catch (Throwable ex) {
    
    
                    throw new IllegalStateException(
                        "Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
                }
            }
        }
        if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
    
    
            if (!(beanDef instanceof AbstractBeanDefinition)) {
    
    
                throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
                                                       beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
            }
            else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
    
    
                logger.info("Cannot enhance @Configuration bean definition '" + beanName +
                            "' since its singleton instance has been created too early. The typical cause " +
                            "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
                            "return type: Consider declaring such methods as 'static'.");
            }
            configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
        }
    }
    if (configBeanDefs.isEmpty()) {
    
    
        // nothing to enhance -> return immediately
        return;
    }

    ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
    for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
    
    
        AbstractBeanDefinition beanDef = entry.getValue();
        // If a @Configuration class gets proxied, always proxy the target class
        beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
        // Set enhanced subclass of the user-specified bean class
        Class<?> configClass = beanDef.getBeanClass();
        Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
        if (configClass != enhancedClass) {
    
    
            if (logger.isTraceEnabled()) {
    
    
                logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
                                           "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
            }
            beanDef.setBeanClass(enhancedClass);
        }
    }
}

八、其他问题

1 AOP的@EnableAspectAutoProxy时机

上面解释过了ConfigurationClass…那个工厂后置处理器扫描进来的,我们去看看

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    
    
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}

这个注解@Import了个register,去里面看看,注解驱动开发的知识告诉我们肯定实现了registerBeanDefinitions方法,他用来注册bd

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
    

    @Override
    public void registerBeanDefinitions(
        AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
        // 去里面看看,他是在里面注册bd的
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
    
    
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
    
    
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
    
    
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

一路委托,最终委托到,好家伙,我们终于看到new RootBeanDefinition了,这不就是new bd。他里面打个断点自己看吧

// AopConfigUtils.java
private static BeanDefinition registerOrEscalateApcAsRequired(
    Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    
    

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    // 
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
    
    
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    
    
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
    
    
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }

    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

我们通过debug发现他就是new bd(AnnotationAwareAspectJAutoProxyCreator.class)

我们进类去看,他实现了SmartInstantiationAwareBeanPostProcessor接口,他是个后置处理器,他会在refresh的下个阶段进行实例化。

更详细的内容看下一篇吧

2 想要整合其他源码怎么做

把第三方源码的工厂后置处理器作为入参传入到处理工厂后置处理器的逻辑中,他会在这个阶段完成逻辑

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

未整理内容

AnnotatedBeanDefinitionReader:

猜你喜欢

转载自blog.csdn.net/hancoder/article/details/111413351
今日推荐