SPRING09_ Bean后置处理器创建过程、SmartInstantiationAwareBeanPostProcessor预测方法调用

文章目录

  • [①. Bean后置处理器创建过程](#①. Bean后置处理器创建过程)
  • [②. SmartInstantiationAwareBeanPostProcessor预测方法调用](#②. SmartInstantiationAwareBeanPostProcessor预测方法调用)

①. Bean后置处理器创建过程

  • ①. 坏境准备,在BeanPostProcessor的无参构造器、postProcessBeforeInitialization以及postProcessAfterInitialization打上断点.以xml的方式启动容器

  • ②. 注册所有的Bean的后置处理器,该方法在finishBeanFactoryInitialization方法之前执行

java 复制代码
@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
	    ......
		//BeanFactory第一次开始创建的时候
		// 工厂创建:告诉子类去刷新自己内部的工厂,BeanFactory第一次开始创建的时候获取刷新好的bean工厂
		// 这里xml解析逻辑,也就是xml在这解析完之后,所以bean的定义信息就有了,也就是说BeanFactory第一次开始创建的时候,有xml解析逻辑
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
			// 工厂增强:执行所有的BeanFactory后置增强器,利用BeanFactory对工厂进行增强或修改
			// 解释下:在finishBeanFactoryInitialization方法之前执行增强逻辑,可以在bean没有创建的时候,就对bean对象进行增强处理(配置类也会在这里解析)
			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// 注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);
			beanPostProcess.end();
			......
}

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
  • ③. PostProcessorRegistrationDelegate类中的方法代理了所有的后置增强、相当于后置处理器的管理员
  • ⑤. 解析registerBeanPostProcessors方法前面代码
java 复制代码
public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	// [1]. 获取到容器中所有的BeanPostProcessor Bean的后置处理器
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 这里还加了一个Bean的检查处理器

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();// 实现了优先级接口的
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();// 内部用的
	List<String> orderedPostProcessorNames = new ArrayList<>();// 实现了排序接口的
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();// 没有实现排序接口的
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 获取所有实现了优先级的PriorityOrdered
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);// 获取到了之后加入到优先级集合中
			if (pp instanceof MergedBeanDefinitionPostProcessor) {//如果处理是MergedBeanDefinitionPostProcessor
				internalPostProcessors.add(pp);// 将其加入到内置处理器
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // bean是否为Ordered排序的
			orderedPostProcessorNames.add(ppName);// 加入排序集合中
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);// 否则加入不是排序集合中
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	// [1]. 首先注册实现了所有PriorityOrdered(优先级)接口的后置处理器
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	// [2]. 接下来注册所有实现了Ordered(排序)接口的后置处理器
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 排序后执行
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	// [3]. 最后,注册所有普通的BeanPostProcessors
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);// 从容器中获取组件
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	.....
}
  • ⑥. 从容器中获取到BeanPostProcessor组件
  1. 这里会遍历,可以看到集合中有4条记录
  2. 会分别去getBean,获取到这四个类型的Bean
  3. 这四个对象会分别调用无参构造器进行初始化处理
java 复制代码
// Now, register all regular BeanPostProcessors.
// [3]. 最后,注册所有普通的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
	BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);// 从容器中获取组件
	nonOrderedPostProcessors.add(pp);
	if (pp instanceof MergedBeanDefinitionPostProcessor) {
		internalPostProcessors.add(pp);
	}
}

  • ⑦. 注册RegisterBeanPostProcessors,Step into进去看看

  • ⑧. 工厂提前保存所有增强器,方便在后面创建Bean的时候直接使用

java 复制代码
/**保存所有的Bean的后置增强器 BeanPostProcessors to apply. */
private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

	if (beanFactory instanceof AbstractBeanFactory) {
		// 所谓的注册就是将后置处理器保存到beanPostProcessors集合中 Bulk addition is more efficient against our CopyOnWriteArrayList there
		((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
	}
	else {
		for (BeanPostProcessor postProcessor : postProcessors) {
			beanFactory.addBeanPostProcessor(postProcessor);
		}
	}
}

public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
	this.beanPostProcessors.removeAll(beanPostProcessors);
	this.beanPostProcessors.addAll(beanPostProcessors);
}
  • ⑨. 至此,注册四个后置处理器就结束了

②. SmartInstantiationAwareBeanPostProcessor预测方法调用

  • ①. 接着上面的断点放行,可以看到来到了SmartInstantiationAwareBeanPostProcessor的predictBeanType方法,下面我们来进行具体的分析
  • ②. 容器12大步 - 注册监听器,Spring时间监听机制在这里开始初始化
  • ③. 获取ApplicationListener在IOC容器在bean注册的名字
java 复制代码
protected void registerListeners() {
	// Register statically specified listeners first.
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	//获取ApplicationListener在IOC容器在bean注册的名字 uninitialized to let post-processors apply to them!
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);// 获取所有的容器中的监听器名字,并保存他们的名字
	}

	// Publish early application events now that we finally have a multicaster...
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

@Override// 获取某个类型的组件在容器中的所有名字
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	assertBeanFactoryActive();
	return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
}
  • ④. Spring底层获取某个类型是先拿到所有的beanDefinitionNames名称集合,遍历这个名称集合,再通过mergedBeanDefinitions去获取到具体的BeanDefinition的信息,进行获取到类型(这个方法很笨)
    因为Spring没有直接保存Class - name[]定义信息的map
java 复制代码
// 获取某一个组件在容器中的名字。
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
	List<String> result = new ArrayList<>();

	//因为Spring没有直接保存Class - name定义信息。只能先拿出beanName,再看是否是指定的类型 Check all bean definitions.
	for (String beanName : this.beanDefinitionNames) {
		// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
		if (!isAlias(beanName)) {
			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// Only check bean definition if it is complete.
				if (!mbd.isAbstract() && (allowEagerInit ||
						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
								!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
					boolean isFactoryBean = isFactoryBean(beanName, mbd);//是不是FactoryBean
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					boolean matchFound = false;
					boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
					boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
					if (!isFactoryBean) {
						if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
							// 只要是没有创建组件的,都会进来这里,这里是cat2进来了,这是因为其他Spring组件在前面都已经创建了,比如后置处理器等
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);// 是否类型匹配
  • ⑤. isTypeMatch方法可以通过后置处理器可以返回自定义的类型

  • ⑥. 调用我们自己实现了SmartInstantiationAwareBeanPostProcessor接口的predictBeanType方法

java 复制代码
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
	Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
	// Apply SmartInstantiationAwareBeanPostProcessors to predict the
	// eventual type after a before-instantiation shortcut.
	if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
		for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
			Class<?> predicted = bp.predictBeanType(targetType, beanName);
			if (predicted != null &&
					(!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
				return predicted;
			}
		}
	}
	return targetType;
}
  • ⑦. 细节点:为什么这里是传了一个cat2来了呢?
  1. 这是因为这个方法可以改变返回的类型,我们在进行到执行registerListeners方法的时候,其他的组件(比如myBeanPostProcessor)已经完2. 成了组件的创建,我们自定义的Cat2还没有完成创建
  2. 这里会把没有完成创建的实列都进行走predictBeanType方法

相关推荐
猷咪6 分钟前
C++基础
开发语言·c++
IT·小灰灰7 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧9 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q10 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳010 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾10 分钟前
php 对接deepseek
android·开发语言·php
vx_BS8133014 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683614 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计27 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673739 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos