• 【Spring-2】refresh方法中的invokeBeanFactoryPostProcessors方法


    在分析这个方法之前,先介绍两个接口:

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
    	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }
    
    public interface BeanFactoryPostProcessor {
    
    	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    两个方法,可以看到传的参数是BeanDefinitionRegistry,ConfigurableListableBeanFactory。spring会调用这个实现了的方法,所以可以得到BeanDefinitionRegistry,ConfigurableListableBeanFactory的实例,得到实例当然就可以操作他们了,改变属性或者手动往里面注册信息等。

    所以这两个接口就是自定义BeanFactory和BeanDefinitionRegistry的。

    下面看看spring是如何调用实现类中的这两个方法的。

    		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
    • 1

    这里怎么会传入getBeanFactoryPostProcessors()呢?因为是实例化AnnotationConfigApplicationContext时候可以添加处理器方法呀。此时就要把这些处理器算进去了。

    进入invokeBeanFactoryPostProcessors方法

    public static void invokeBeanFactoryPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
    		Set<String> processedBeans = new HashSet<>();
    	
    		// 先处理bd注册器,
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    			// 用来保存bean实例工厂的处理器
    			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    			// 用来保存bd注册器的处理器
    			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    			
    			// 这里注意下,先遍历我们通过手动添加的处理器,这里会调用处理器的注册bd方法
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryProcessor =
    							(BeanDefinitionRegistryPostProcessor) postProcessor;
    					registryProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryProcessors.add(registryProcessor);
    				}
    				else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    
    	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    下面一块单独分析

    		    // 重头戏开始了。先从bean工厂中找出类型是BeanDefinitionRegistryPostProcessor的bd名称
    		    // 
    			String[] postProcessorNames =
    					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			// 遍历名称,如果这个bd的类型是PriorityOrdered,类型,就实例化处理器,同时加入集合。
    			// 注意的是此时容器中都是spring自己bd
    			for (String ppName : postProcessorNames) {
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			// 排序,实现了order接口
    			sortPostProcessors(currentRegistryProcessors, beanFactory);
    			registryProcessors.addAll(currentRegistryProcessors);
    			// 执行处理方法
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    			currentRegistryProcessors.clear();
    
    		// 拓展一点知识,我们自己注解配置的类,希望注册到容器的逻辑就是这里。ConfigurationClassPostProcessor
    		private static void invokeBeanDefinitionRegistryPostProcessors(
    					Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
    		
    				for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
    					StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
    							.tag("postProcessor", postProcessor::toString);
    					postProcessor.postProcessBeanDefinitionRegistry(registry);
    					postProcessBeanDefRegistry.end();
    				}
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    从注册器中找出BeanDefinitionRegistryPostProcessor类型的bd名称,如果是PriorityOrdered类型的。实例化处理器。调用处理器的postProcessBeanDefinitionRegistry方法。
    所有的处理器方法都是spring自己的,而在此步骤ConfigurationClassPostProcessor中的方法得到执行,开始向IOC容器中注册db。在执行完invokeBeanDefinitionRegistryPostProcessors后,我们写的所有处理器都注册到了容器中。

    通过ConfigurationClassPostProcessor类将自己写的类注册到容器中。

    下面的处理器中开始包含我们自己的。执行实现了order接口的

    			// 同样是找BeanDefinitionRegistryPostProcessor类型。
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			for (String ppName : postProcessorNames) {
    				// 如果没有处理过,并且是Ordered类型的。加入集合。
    				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);
    			// 执行处理器的postProcessBeanDefinitionRegistry
    			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    			currentRegistryProcessors.clear();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    执行普通的处理器。

    			// 最后执行所有没有处理的处理器。也就是普通的处理器
    			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);
    						reiterate = true;
    					}
    				}
    				sortPostProcessors(currentRegistryProcessors, beanFactory);
    				registryProcessors.addAll(currentRegistryProcessors);
    				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    				currentRegistryProcessors.clear();
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    最后是找出所有的普通的处理器。

    
    
    			// registryProcessors是注册器的处理器集合
    			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    			// regularPostProcessors是实例工厂的处理器集合
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    			// public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor BeanDefinitionRegistryPostProcessor 是子接口
    		
    		// 调用处理器的postProcessBeanFactory方法
    		private static void invokeBeanFactoryPostProcessors(
    			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
    		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
    			StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
    					.tag("postProcessor", postProcessor::toString);
    			postProcessor.postProcessBeanFactory(beanFactory);
    			postProcessBeanFactory.end();
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    流程梳理

    1. 从注册器中找到BeanDefinitionRegistryPostProcessor类型的类
    2. 先处理实现了PriorityOrdered接口的,执行处理器的postProcessBeanDefinitionRegistry
    3. 再处理实现了Ordered接口的类,执行处理器的postProcessBeanDefinitionRegistry
    4. 最后处理其他的,执行处理器的postProcessBeanDefinitionRegistry
    5. 因为BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcessor接口。最后把之前找到的所有BeanDefinitionRegistryPostProcessor类型的类,执行它们的postProcessBeanFactory方法。

    下面分析下BeanFactoryPostProcessor的逻辑

    		// 找到BeanFactoryPostProcessor类型的类
    		String[] postProcessorNames =
    				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
    		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    		List<String> orderedPostProcessorNames = new ArrayList<>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    		// 遍历找到的所有BeanFactoryPostProcessor类型的类
    		for (String ppName : postProcessorNames) {
    			// 如果之前处理过,不做处理
    			if (processedBeans.contains(ppName)) {
    				// skip - already processed in first phase above
    			}
    			// 加入到各自的列表中
    			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);
    			}
    		}
    
    
    
    		// 执行, BeanFactoryPostProcessors that implement PriorityOrdered.
    		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// 之后执行the BeanFactoryPostProcessors that implement Ordered.
    		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    		for (String postProcessorName : orderedPostProcessorNames) {
    			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		sortPostProcessors(orderedPostProcessors, beanFactory);
    		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    		// 最后执行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.clearMetadataCache();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    流程梳理

    1. 先从注册器中取出BeanFactoryPostProcessor类型的类,根据PriorityOrdered,Ordered,普通,分别实例化,执行invokeBeanFactoryPostProcessors方法。
    2. 执行postProcessBeanDefinitionRegistry方法。之后再执行该类型的postProcessBeanFactory方法。
      之后从beanFactory中取出所有的BeanFactoryPostProcessor类型的类,执行它们的postProcessBeanFactory方法。

    注意:BeanDefinitionRegistryPostProcessor类型的类只有ConfigurationClassPostProcessor。通过该类将我们写的要注入的bean注册进beanFactory。之后在找的时候,多半是自己写的BeanDefinitionRegistryPostProcessor的类。

    这个方法的主要功能是实例化BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的实例。同时执行各处理器的处理方法。

    此时,已经实例化所有的bean工厂的处理器并执行了方法。

  • 相关阅读:
    Java基础接口
    微服务:高性能网关 ShenYu简介
    vue+element ui读取excel文件
    linux(CentOS安装,创建新的虚拟机)
    免费在线pdf处理工具:pdf文件压缩;pdf文件转word
    基于SSM的校园服务平台管理系统设计与实现
    【juc学习之路第9天】屏障衍生工具
    web前端之uniApp实现选择时间功能
    软考高级系统架构设计师系列之:信息系统综合知识常考知识点详细总结
    SuperMap 是个什么鬼
  • 原文地址:https://blog.csdn.net/qq_34501351/article/details/114123727