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

相关推荐
The Future is mine11 分钟前
Python计算经纬度两点之间距离
开发语言·python
Enti7c11 分钟前
HTML5和CSS3的一些特性
开发语言·css3
腥臭腐朽的日子熠熠生辉17 分钟前
解决maven失效问题(现象:maven中只有jdk的工具包,没有springboot的包)
java·spring boot·maven
Harrison_zhu18 分钟前
Ubuntu18.04 编译 Android7.1代码报错
android
爱吃巧克力的程序媛19 分钟前
在 Qt 创建项目时,Qt Quick Application (Compat) 和 Qt Quick Application
开发语言·qt
ejinxian19 分钟前
Spring AI Alibaba 快速开发生成式 Java AI 应用
java·人工智能·spring
杉之24 分钟前
SpringBlade 数据库字段的自动填充
java·笔记·学习·spring·tomcat
圈圈编码44 分钟前
Spring Task 定时任务
java·前端·spring
俏布斯1 小时前
算法日常记录
java·算法·leetcode
独好紫罗兰1 小时前
洛谷题单3-P5719 【深基4.例3】分类平均-python-流程图重构
开发语言·python·算法