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方法

相关推荐
重生之我在20年代敲代码18 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文19 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people23 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
qmx_071 小时前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战1 小时前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
Dingdangr3 小时前
Android中的Intent的作用
android
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
GEEKVIP3 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑