Spring5源码-BeanFactoryPostProcessor接口分析

承接上文Spring源码-AnnotationConfigApplicationContext分析
在AnnotationConfigApplicationContext构造函数中,调用了register(componentClasses)将配置类转换为BeanDefinition注册到了Spring 容器中,在执行refresh()方法前beanDefinitionMap中内容如下,在这里插入图片描述
那其他的BeanDefinition什么时候解析呢?比如还有如下类

@Data
@Component
public class Cat {private String name;}
@Data
public class Dog {private String name;}
@Data
public class Person {private String name;}

@ComponentScan
@Configuration
@Import(Dog.class)
public class AppConfig {
    @Bean
    public Person myPerson() {return  new Person();}
}

答案是在refresh方法的invokeBeanFactoryPostProcessors(beanFactory)中,该方法用来调用实现BeanFactoryPostProcessor接口和实现BeanDefinitionRegistryPostProcessor接口的类。ConfigurationClassPostProcessor就实现了BeanDefinitionRegistryPostProcessor接口,并且优先级最高。它就是专门负责将满足条件的类解析为BeanDefinition的。从源码注释可以看出这两个接口的作用。

BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor接口

BeanFactoryPostProcessor接口:用于在Spring加载BeanDefinition之后、实例化Bean之前对BeanDefinition进行修改,可以参考PropertyResourceConfigurer其具体实现。

BeanDefinitionRegistryPostProcessor接口:用于注册新的bean定义,这个bean也可以是BeanFactoryPostProcessor。也不限于只注册1个,可以参考mybatis-spring中的MapperScannerConfigurer类,直接扫描指定包下的所有Mapper封装成 BeanDefinition 并加载到 BeanFactory 中。

两个接口的区别

BeanFactoryPostProcessor用于修改bean定义;
BeanDefinitionRegistryPostProcessor用于新增bean定义,比BeanFactoryPostProcessor更早调用,继承自BeanFactoryPostProcessor;

两个接口的注册方式

① 硬编码。比如通过BeanConfigurableApplicationContext的addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)方法;该方式Order失效(也就是不会排序)。另外也有其他方式,比如调用registerBean方法。

② 通过bean定义(配置的方式),Spring会自动检测,并在创建任何其他 bean 之前调用。比如:

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("MyBeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry方法执行了");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    	BeanDefinition person = registry.getBeanDefinition("myPerson");
        person.setScope("prototype");
        registry.registerBeanDefinition("myPerson",person);
        System.out.println("MyBeanDefinitionRegistryPostProcessor postProcessBeanFactory方法执行了");
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

invokeBeanFactoryPostProcessors方法源码解析

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()

//beanFactoryPostProcessors为通过调用addBeanFactoryPostProcessor方法添加的BeanFactoryPostProcessor
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		//存放已经执行过的PostProcessor
		Set<String> processedBeans = new HashSet<>();
        //beanFactory是DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

			//BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor
            //将实现BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口的类分开保存到对应的list中
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			//如果是实现了BeanDefinitionRegistryPostProcessor接口,直接调用
			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<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			//这里调用的是容器中已解析为BeanDefinition的且实现了BeanDefinitionRegistryPostProcessor接口的PostProcessor
			//调用顺序:PriorityOrdered、Ordered、剩下的
			//如果未向容器中手动注册实现BeanDefinitionRegistryPostProcessor的BeanDefinition,这里满足条件的就只有ConfigurationClassPostProcessor,
			//这是因为在AnnotatedBeanDefinitionReader对象创建时注册了internalConfigurationAnnotationProcessor对应的BeanDefinition,
			//此时其他的类尚未解析为BeanDefinition,ConfigurationClassPostProcessor就是专门来做这个的。
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
			    //先调用实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				    //注册Bean,这里已经实例化了,后面可以直接用了
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			//此时ConfigurationAnnotationProcessor的postProcessBeanDefinitionRegistry方法得到调用,
			//执行完成后,所有符合条件的类都会被解析为BeanDefinition,注册到Spring容器中
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			//其次调用实现Ordered接口的BeanDefinitionRegistryPostProcessor,因为上一步已经注册了所有的BeanDefinition,
			//所有通过配置的方式注册的BeanDefinitionRegistryPostProcessor接下来就可以被调用了
			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);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			//最后调用剩下的BeanDefinitionRegistryPostProcessor
			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();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			//调用BeanFactoryPostProcessors的postProcessBeanFactory方法,BeanDefinitionRegistryPostProcessors先执行
			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,同样调用顺序为:PriorityOrdered、Ordered、剩下的
		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<>();
		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);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke 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);

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

总结

1、在refresh方法的invokeBeanFactoryPostProcessors(beanFactory)中,实现了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的类都会被调用。

2、ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,并且优先级最高,除了硬编码的之外,它最先得到执行,执行完后所有满足条件的类都将被解析为BeanDefinition并注册到Spring容器中。

3、BeanFactoryPostProcessor用于修改bean定义,BeanDefinitionRegistryPostProcessor用于新增bean定义,对于动态添加或修改 bean 定义非常有用。

4、注册BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor可以通过硬编码,此种方式执行顺序得不到保证;也可以通过Bean定义(配置)方式,Spring自动检测,有执行顺序。

5、BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor执行顺序

① 调用硬编码的BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法

② 调用配置的BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法,优先级:PriorityOrdered>Ordered>剩余的

③ 到这里BeanDefinitionRegistryPostProcessor自己的方法调完了,开始调用父接口BeanFactoryPostProcessors的postProcessBeanFactory方法

④ 调用硬编码的BeanFactoryPostProcessors接口的postProcessBeanFactory方法

⑤ 调用配置的BeanFactoryPostProcessors接口的postProcessBeanFactory方法,优先级:PriorityOrdered>Ordered>剩余的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值