spring的后置处理器今天我来给你肤浅的讲讲

spring的后置处理器是spring中很重要的一块,可以说你的项目能启动后置处理器有一大半的功劳,今天不会具体讲某个后置处理(先把坑挖好,日后再说),只会讲到spring是如果获取这些后置处理的,又是按照什么顺序来执行这些后置处理器的。

1、bean的后置处理器都有哪些

a.实现了BeanFactoryPostProcessor接口的类,这个接口还有个子类BeanDefinitionRegistryPostProcessor,他们从代码上的区别是BeanDefinitionRegistryPostProcessor比他的父类多一个方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),在执行上的区别是在相同的情况下实现了BeanDefinitionRegistryPostProcessor会比只实现了BeanFactoryPostProcessor更早执行。这两个接口你不管执行那个你都可以参与到容器的初始化当中。

b.实现了BeanPostProcessor接口的类

a和b的主要区别是a的发力点在BeanDefinition而a的发力点在于bean,你可以发现在spring当中有好多实现了这几个接口的,那么spring是怎么觉得到底是谁先来执行的呢?除了上面的接口还有Ordered和PriorityOrdered接口,你可以实现这两个接口来调整后置处理器在执行过程中的先后顺序。

2、spring是怎么找到你这些后置处理器的

想要参与bean的创建,你首先的让spring能找到你的后置处理器,包括程序员自己的和spring自己的后置处理器,spring是怎么获取到的呢?下面从代码中一探究竟

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	this(); //在构造ApplicationContext时调用了无参的构造方法
	register(componentClasses);
	refresh(); //这个方法很关键很重要这个方法弄明白了你spring就通透了
}

//无参的构造方法
public AnnotationConfigApplicationContext() {
	StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
	//read赋值了BeanDefinitionReader
	this.reader = new AnnotatedBeanDefinitionReader(this);
	createAnnotatedBeanDefReader.end();
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

//这个方法产生了一个reader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	//他既然叫注册配置处理,那么不难感觉到这一步和注解的处理程序有关,那我们在启动类的注解上添加了扫描的路径,大概率和他有关系没跑了(不用想确实是他,我们往下看)
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 
}


//AnnotationConfigUtils.registerAnnotationConfigProcessors() 有删减
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	/*
	这里获取到了beanFactory,但是beanFactory的创建其实是这样的,
	AnnotationConfigApplicationContext继承了GenericApplicationContext
	在GenericApplicationContext的构造方法里new了一个DefaultListableBeanFactory,这里获取到的就是他
	*/
	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		/*
		这里放了ConfigurationClassPostProcessor的bd到beanFactory中
		这个ConfigurationClassPostProcessor很重要通过他可以扫描到很多东西,当然还有其他的功能
		*/
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		/*
		registerPostProcessor把这个bd注册到beanFactory厂里了,
		也就是在registerAnnotationConfigProcessors()这个方法里最基本的几个bd被放到了beanFactory中,
		在registerAnnotationConfigProcessors()放进去的这几个bd可以说是梦开始的地方
		*/
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	//...省略了还有其他的bd放到beanFactory中了
	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		//... jpa是亲儿子啊,Mybatis就没这待遇 代码省略le
	}
	return beanDefs; //这个地方虽然返回了但是没有用到,registerPostProcessor是重点
}

所以spring自己的后置处理器是通过以上的形式被手动注册到beanFactory中的。

刚我们讲到了ConfigurationClassPostProcessor的bd被放到了beanFactory中,我们自己的后置处理器是怎么被发现的答案就在这个类里面,我们来具体看看这个类他实现的接口包括了BeanDefinitionRegistryPostProcessor接口PriorityOrdered接口根据上面讲的,这个类是一个后置处理器,而且是处理beanDefinition的,他相当重要。

// ConfigurationClassPostProcessor.java postProcessBeanDefinitionRegistry()
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	//...省略le
	processConfigBeanDefinitions(registry);
}

//最后这个方法会一路调用到ConfigurationClassParser.java的doProcessConfigurationClass()方法
@Nullable
protected final SourceClass doProcessConfigurationClass(
		ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
		throws IOException {

	//...省略了

	// 处理 @ComponentScan 注解
	Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
	if (!componentScans.isEmpty() &&
			!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
		for (AnnotationAttributes componentScan : componentScans) {
			// 解析类上的@ComponentScan注解 立即扫描 
			Set<BeanDefinitionHolder> scannedBeanDefinitions =
					this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
			//检查扫描的定义集是否有任何进一步的配置类,并在需要时递归解析
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	//处理所有的@Import 注解
	processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

	// 处理所有的 @ImportResource 注解
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// 处理 @Bean 方法
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	//...省略了
	return null;
}

由于你的所有的后置处理器都是要交给spring管理的所以,在解析@ComponentScan的时候会把它扫描出来并生成bd注册到beanFactory中,在beanFactory中有一个getBeanNamesForType()方法就可以根据类型拿到bean的名字,这样我们只需要调用这个方法就可以拿到对应的后置处理器了。

3、后置处理器的执行顺序

真正那些这些后置处理器干活的是PostProcessorRegistrationDelegate.java的invokeBeanFactoryPostProcessors()方法,这个方法有两个参数beanFactory和beanFactoryPostProcessors,beanFactoryPostProcessors是传进来的BeanFactoryPostProcessor,执行顺序为:

a. beanFactoryPostProcessors 里面实现了 BeanDefinitionRegistryPostProcessor接口的先执行postProcessBeanDefinitionRegistry 并加入registryProcessor;没有实现的加入regularPostProcessors
b.beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口和PriorityOrdered接口的 排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry
c.beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口和Ordered接口的 排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry
d.beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口的 排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry
e. 执行registryProcessors里面的postProcessBeanFactory
f. 执行regularPostProcessors里面的postProcessBeanFactory
i. beanFactory 里面 实现了BeanFactoryPostProcessor、PriorityOrdered接口的 排序后执行postProcessBeanFactory
g. beanFactory 里面 实现了BeanFactoryPostProcessor、Ordered接口的 排序后执行postProcessBeanFactory
k. beanFactory 里面 实现了BeanFactoryPostProcessor接口的 排序后执行postProcessBeanFactory

口说无凭上代码

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	
	Set<String> processedBeans = new HashSet<>();

	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;
				/*
				beanFactoryPostProcessors 里面实现了BeanDefinitionRegistryPostProcessor接口的
				先执行postProcessBeanDefinitionRegistry 并加入registryProcessor
				*/
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				//没有实现的加入regularPostProcessors
				regularPostProcessors.add(postProcessor);
			}
		}

		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
		/*
		beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口和PriorityOrdered接口的 
		排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry
		 */
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory); //这里是排序
		registryProcessors.addAll(currentRegistryProcessors);
		//执行后置处理器 ConfigurationClassPostProcessor里面的方法就是在这被执行的
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
		currentRegistryProcessors.clear();

		/*
		beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口和Ordered接口的 
		排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry 
		*/
		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();

		/*
		beanFactory 里面 实现了BeanDefinitionRegistryPostProcessor接口的 
		排序后加入到registryProcessors 并执行postProcessBeanDefinitionRegistry
		*/
		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();
		}

		// 执行registryProcessors里面的postProcessBeanFactory
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		//执行regularPostProcessors里面的postProcessBeanFactory
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

	else {
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	//beanFactory 里面 实现了BeanFactoryPostProcessor接口的 排序后执行postProcessBeanFactory
	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)) {
			// 实现了BeanFactoryPostProcessor、PriorityOrdered接口的加入priorityOrderedPostProcessors
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			// 实现了BeanFactoryPostProcessor、Ordered接口的加入orderedPostProcessorNames
			orderedPostProcessorNames.add(ppName);
		}
		else {
			//实现了BeanFactoryPostProcessor接口的加入nonOrderedPostProcessorNames
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 先执行priorityOrderedPostProcessors
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// 再执行orderedPostProcessorNames
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// 最后执行nonOrderedPostProcessors
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
	beanFactory.clearMetadataCache();
}

这样BeanFactoryPostProcessor的处理就结束了

BeanPostProcessor的处理是注册制的,他会把所有的BeanPostProcessor注册到beanFactory里的beanPostProcessors(这是个List<BeanPostProcessor>)里面,注册的顺序是实现了PriorityOrdered在前面,实现了Ordered紧随其后,最后是只实现了BeanPostProcessor的
然后这些后置处理器的执行是在bd生成bean(调用getBean()方法)的时候。
注册BeanPostProcessor的代码在PostProcessorRegistrationDelegate.java的registerBeanPostProcessors()方法里面
使用这些后置处理器是在AbstractAutowireCapableBeanFactory.java的initializeBean()方法里面

if (mbd == null || !mbd.isSynthetic()) {
	//执行前处理
	wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

//...中间有省略
if (mbd == null || !mbd.isSynthetic()) {
	//执行后处理
	wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

至此spring的后置处理器的处理流程你大致已经了解了,欢迎评论区!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值