一、前言
文章目录:Spring源码深度解析:文章目录
二、BeanPostProcessor
所谓的BeanPostProcessor翻译过来就是Bean后处理器。
1. 什么是 BeanPostProcessor
BeanPostProcessor是 Spring提供给我们的一个非常重要的扩展接口,并且Spring内部的很多功能也是通过 BeanPostProcessor来完成的(目前看到最典型的就是AnnotationAwareAspectJAutoProxyCreator的 注入)。
2. BeanPostProcessor 的种类
BeanPostProcessor 在Spring 中的子类非常多(idea 显是有46个),比如
- InstantiationAwareBeanPostProcessorAdapter: 在Spring 的- bean加载过程中起了非常重要的作用
- AnnotationAwareAspectJAutoProxyCreator:- bean创建过程中的 属性注入时起作用
- AspectJAwareAdvisorAutoProxyCreator: Aspect 的 AOP 功能实现也全仰仗- BeanPostProcessor的特性。
3. BeanPostProcessor 的创建
个人认为Bean的创建时可以认为分为两个过程: 一是Bean对应的BeanDefinition的创建。二是Bean实例的创建。
因为在 Spring容器中,Bean的创建并非仅仅通过反射创建就结束了,在创建过程中,需要考虑到Bean针对Spring容器中的一些属性,所以BeanDefinition中不仅仅包含了Bean Class文件信息,还包含了 当前Bean在Spring容器中的一些属性,比如在容器中的作用域、是否懒加载、别名等信息。当Bean进行实例化创建时需要依赖于对应的BeanDefinition提供对应的信息。
BeanDefinition的创建在 Spring 启动时对BeanFactoryPostProcessor的处理。
 详参:
 Spring源码深度解析:五、BeanFactoryPostProcessor的处理
Spring源码深度解析:六、ConfigurationClassPostProcessor
Bean 实例的创建在Spring 启动时的收尾工作
 详参:
 Spring源码深度解析:三、容器的刷新 - refresh()
而由于BeanPostProcessor是参与了Bean创建过程。所以其创建一定在普通Bean之前。实际上BeanPostProcessor的创建时在Spring启动时容器刷新的时候。
BeanPostProcessor的BeanDefinition创建时机和普通Bean没有区别,都是在Spring 启动时的BeanFactoryPostProcessor中完成(确切的说是ConfigurationClassPostProcessor中完成)。
而BeanPostProcessor的实例创建要优先于普通bean创建,Spring启动过程中会调用AbstractApplicationContext#registerBeanPostProcessors方法。 在这个方法中,Spring 会从容器中获取到所有BeanPostProcessor类型的beanName, 通过beanFactory.getBean方法获取到对应实例,进行排序后注册到BeanFactory.beanPostProcessors属性中,其中BeanFactory.beanPostProcessors的定义如下
	private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();
当容器需要执行 BeanPostProcessor方法时可以直接从beanPostProcessors中获取即可。
三、基本介绍
日常使用中,我们一般编写一个类来实现BeanPostProcessor或者 InstantiationAwareBeanPostProcessor接口,根据每个方法的调用时机,来完成响应的工作。
 下面介绍一下接口方法,这里通过InstantiationAwareBeanPostProcessor接口来介绍 。InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,在 BeanPostProcessor基础上又扩展了三个方法。
@Component
public class DemoPostProcessor implements InstantiationAwareBeanPostProcessor {
	//InstantiationAwareBeanPostProcessor 提供的方法, 在 Class<T> -> T 的转换过程中
	// 此时bean还没创建,可以通过这方法代替 Spring 容器创建的方法
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		System.out.println("DemoPostProcesser.postProcessBeforeInstantiation   ###  1");
		return null;
	}
	//InstantiationAwareBeanPostProcessor 提供的方法, 返回的值代表是否需要继续注入属性,
	// 如果返回true,则会调用postProcessProperties和postProcessPropertyValues 来注入属性
	// 此时bean已经创建,属性尚未注入
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		System.out.println("DemoPostProcesser.postProcessAfterInstantiation   ###  2");
		return true;
	}
	//InstantiationAwareBeanPostProcessor 提供的方法,可以在这个方法中进行bean属性的注入, 这个方法已经过时,使用postProcessProperties 代理
	// 只有postProcessAfterInstantiation 返回true 时 且 postProcessProperties 返回 null 时调用
	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		System.out.println("DemoPostProcesser.postProcessPropertyValues   ###  3");
		return pvs;
	}
	// BeanPostProcessor 提供的方法,在bean初始化前调用,这时候的bean大体已经创建完成了,在完成一些其他属性的注入
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("DemoPostProcesser.postProcessBeforeInitialization   ###  4");
		return bean;
	}
	// BeanPostProcessor 提供的方法,在bean初始化后调用,这时候的bean 已经创建完成了
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("DemoPostProcesser.postProcessAfterInitialization   ###  5");
		return bean;
	}
}
@Configuration
@ComponentScan("com.wts.BeanPostProcessorTest")
public class SpringConfigPostProcessor {
}
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfigPostProcessor.class);
		Object demoPostProcessor = applicationContext.getBean("demoPostProcessor");
		System.out.println(demoPostProcessor);
	}
}

四、源码中的调用场景
下面为了方便描述,进行一些简化写法,为了后面描述方便
 BP : BeanPostProcessor
 IBP : InstantiationAwareBeanPostProcessor
 SBP : SmartInstantiationAwareBeanPostProcessor
其结构如下图:
 
 这里就不具体贴出多少代码。简单解释一下调用场景
Spring 在启动过程中,会将所有实现了BeanPostProcessor接口的子类保存到 AbstractBeanFactory中的beanPostProcessors集合中,如下:
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
在适当的时候(这个适当的时候就根据 每个接口方法定义的意义来判断), Spring会获取所有的BeanPostProcessor子类集合,即beanPostProcessors,经过类型过滤后,调用对应的方法。比如,就是对InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法的调用流程(其余方法的调用也类似):
 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		// 获取所有BeanPostProcessor进行遍历
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			// 因为只有 InstantiationAwareBeanPostProcessor  类型才有postProcessBeforeInstantiation 方法,所以这里要判断一下是不是 InstantiationAwareBeanPostProcessor   类型
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 调用postProcessBeforeInstantiation方法
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}
1. InstantiationAwareBeanPostProcessor
下面来介绍在 Spring 创建流程中 每个方法的实际调用位置:
1.1. postProcessBeforeInstantiation
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法在Bean创建之前调用,我所理解的目的是替换Spring 容器创建bean, 当InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation返回不为null时,则不会再通过Spring 创建bean,而是使用 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation返回的bean。
AbstractAutowireCapableBeanFactory#createBean()
 
 
 resolveBeforeInstantiation方法内容如下,可以看到 当 applyBeanPostProcessorsBeforeInstantiation方法(applyBeanPostProcessorsBeforeInstantiation调用了postProcessBeforeInstantiation方法) 返回值不为 null,则会调用 applyBeanPostProcessorsAfterInitialization方法,从而调用postProcessAfterInitialization方法。因为这里bean返回不为null,则代表bean创建成功了,就会调用创建成功后的方法,即postProcessAfterInitialization。
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		// 如果尚未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			// 当前类并非合成类 && 存在 BeanPostProcessor (后处理器)
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				// 1. 获取目标类
				Class<?> targetType = determineTargetType(beanName, mbd);
				// 2. 实例前的后处理器应用
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						// 3. 实例后的后处理器应用
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
这里需要注意,在resolveBeforeInstantiation方法中,当bean != null时 调用了applyBeanPostProcessorsAfterInitialization方法,即 BeanPostProcessor.postProcessAfterInitialization方法。这是因为如果bean != null, 则说明 bean 的创建已经完成,那么这里则是最后调用bean 的后置处理的机会,即调用BeanPostProcessor.postProcessAfterInitialization方法的最后机会。
1.2. postProcessAfterInstantiation & postProcessPropertyValues
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 、InstantiationAwareBeanPostProcessor.postProcessPropertyValues的调用场景只有一处,在AbstractAutowireCapableBeanFactory#populateBean()方法中,此时bean已经创建完成,正在进行属性注入。而InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation的返回值决定是否继续注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		...
		// 调用 postProcessAfterInstantiation 方法吗,如果返回false,直接return;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
		... 
		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				// 3. 成员变量的注入
				// 调用了InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,来进行设值后处理
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						// 调用设值
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			// 如果需要检查
			if (needsDepCheck) {
				// 依赖检查,对应 depends-on属性,3.0 已弃用
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}
	...
	}
通过代码我们可以比较清楚的看到整体逻辑:
- 若InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation返回true,才会执行下面步骤
- 调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues注入属性
2. BeanPostProcessor
2.1. postProcessBeforeInitialization
BeanPostProcessor.postProcessBeforeInitialization调用时机是bean已经创建完成,但是尚未初始化,即一些属性配置尚未完成(我看到的就一个init-method的配置)。使用场景也只有一处,即
 AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)。
程序走到这里,代表resolveBeforeInstantiation方法中的 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation并未代理bean的创建,在这里则是由Spring 创建的bean的时候来调用。
AbstractAutowireCapableBeanFactory#initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		// 对特殊的bean进行处理: 实现了Aware、BeanClassLoaderAware、BeanFactoryAware的处理。
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				// 激活Aware方法
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		Object wrappedBean = bean;
		// 初始化前
		if (mbd == null || !mbd.isSynthetic()) {
			// 调用了bean前处理器的方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
		// 初始化
		try {
			// 激活自定义的init的方法。
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		// 初始化后
		if (mbd == null || !mbd.isSynthetic()) {
			// 调用bean后处理器的方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
2.2. postProcessAfterInitialization
BeanPostProcessor.postProcessAfterInitialization的调用都被封装到 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()方法中。
而applyBeanPostProcessorsAfterInitialization()方法的调用在下面三个方法中调用:
- AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
- AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)
- AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean
2.2.1 resolveBeforeInstantiation
resolveBeforeInstantiation方法的调用有如下三处:
-  AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])这里的调用实际上就是上面讲的InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()的调用后续,所以这里不再重复
-  AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck()
-  AbstractAutowireCapableBeanFactory#getNonSingletonFactoryBeanForTypeCheck()
2.2.2 initializeBean
上面介绍 BeanPostProcessor.postProcessBeforeInitialization的时候已经说了,所以这里不再赘述
2.2.3 postProcessObjectFromFactoryBean
在FactoryBeanRegistrySupport#getObjectFromFactoryBean中调用,在从FactoryBean中获取bean时调用,在此调用可以替换掉FactoryBean中的返回的bean。
3. SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor在InstantiationAwareBeanPostProcessor之上又扩展了三个方法,不过我们一般不会使用,所以这里简单叙述一下SmartInstantiationAwareBeanPostProcessor三个方法的作用
- Class<?> predictBeanType(Class<?> beanClass, String beanName): 在进行- bean类型匹配时调用,返回值和期望值进行匹配。
- Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName): 在Spring加载- bean的时候,判断是否需要通过构造注入时,如果返回的值不为空,则进行有参构造注入。
AbstractAutowireCapableBeanFactory#createBeanInstance()
		// determineConstructorsFromBeanPostProcessors 中调用了  determineCandidateConstructors 方法,如果ctors != null, 则进行有参构造autowireConstructor
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
Object getEarlyBeanReference(Object bean, String beanName): 在 Spring 解决循环依赖时候使用,返回的值将作为ObjectFactory的保存的Object,用于循环依赖的提前暴露。
AbstractAutowireCapableBeanFactory#doCreateBean()
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// getEarlyBeanReference 的返回值作为 ObjectFactory 的返回值保存到singletonFactories缓存中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

 以上:内容部分参考
 《Spring源码深度解析》
 如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正



















