【Spring】典型 BeanPostProcessor 的调用时机及代表实现类总结

前言

BeanPostProcessorSpring 留给我们让我们自定义拓展 bean实例 生命周期的 钩子 接口

本文总结几类核心 BeanPostProcessor 的调用时机、顺序,以及几个代表实现类的业务逻辑

该文可以看作是下文的一个延伸与补充 

Spring —— BeanPostProcessor 后处理器梳理

行文顺序以创建 bean实例 时调用后处理器的时机为准

1)SmartInstantiationAwareBeanPostProcessor#predictBeanType

  • 该方法调用处较多,入口为 AbstractApplicationContext#getBeanNamesForType,主要用于推断 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法返回的 bean 类型
  • 默认情况下遵从默认实现返回 null,但因为 AbstractAutoProxyCreatorpostProcessBeforeInstantiation 方法中是可能提前返回 代理实例 的,因此 AbstractAutoProxyCreator 也给出了对应的 predictBeanType 方法实现

2)InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

此方法调用处在 AbstractAutowireCapableBeanFactory#createBean 方法中,创建 bean实例对象 之前,主要是进行实例化前的处理

根据它的方法名也不难猜测:
postProcessBeforeInstantiation:实例化之前处理
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		RootBeanDefinition mbdToUse = mbd;

		/**
		 * 此处是确保 beanClass 已解析完成
		 */
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
		}

		try {
			/**
			 * 这里会先调用一次 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法
			 * 如果返回一个 null 则会短路其生命周期,执行 postProcessAfterInitialization 后返回
			 *
			 * 在 AOP 代理阶段,此处是有可能提前短路的
			 */
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
		}

		try {
			// 创建 bean实例 并返回
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
		catch (Throwable ex) {
			
		}
	}
  • bean实例对象 实例化之前,调用 resolveBeforeInstantiation 方法,如果返回非 null 实例,则直接作为 createBean 的结果返回
  • resolveBeforeInstantiation 的逻辑为:执行所有 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法,如果有返回非 null 对象,则短路其生命周期,直接执行 postProcessAfterInitialization 方法后返回
  • 通常情况下,此处都是返回 null,但在 AOP 的实现中,InstantiationAwareBeanPostProcessor 的实现类 AbstractAutoProxyCreator:如果指定了 TargetSource,则此处会提前返回对应的 代理对象,即:短路剩余生命周期后直接返回

3)SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors

该方法的调用时机在创建实例的 AbstractAutowireCapableBeanFactory#createBeanInstance 方法中,一般情况下,初次获取的 bean 在没有 factoryMethod@Bean 注解方法)时,便需要推断其构造方法

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		
		// ...

		// 如果指定 InstanceSupplier,则直接通过它获取实例
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 如果存在 FactoryMethod,比如 @Bean 注解的对应方法,则依此获取实例
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		/**
		 * 如果已经解析过,便直接创建即可
		 */
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		/**
		 * 交给所有 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 来推断,
		 * 		返回第一个不为空的构造器数组
		 */
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 默认构造
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		return instantiateBean(beanName, mbd);
	}
  • 如果没有指定 InstanceSupplier 或者没有对应的 factoryMethod,便会执行所有 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors,返回第一个不为空的 构造器数组
  • factoryMethod 主要是在 配置类 解析时,@Bean 方法会被解析成对应实例的 factoryMethod
  • 一般地,该逻辑默认由 AutowiredAnnotationBeanPostProcessor 实现:在解析到对应的构造方法后,则会基于此构造方法来构造实例,实现对于构造方法中诸如 @Autowired 参数的赋值

4)MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition

该方法的调用在 AbstractAutowireCapableBeanFactory#doCreateBean 方法中,当创建完目标 bean 对应的实例对象后,此处对对应的 BeanDefinition 进行后处理

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		/**
		 * 构造(或从缓存获取)对应 bean实例 的 BeanWrapper
		 */
		BeanWrapper instanceWrapper  = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		/**
		 * 实例创建完成后,调用所有 
		 * 		MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
		 * 		对目标 bean实例 的 BeanDefinition 进行后处理	
		 */
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					
				}
				mbd.postProcessed = true;
			}
		}

		// ...
			
	}
  • BeanWrapper 是一个基于 内省 给实例属性赋值的 PropertyAccessor,唯一实现类 BeanWrapperImpl
  • 在实例对应的 BeanWrapper 创建完成后,回调用所有 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 对目标 beanBeanDefinition 进行后处理
  • 此处的实现类较多,也是 Spring 的一个核心拓展点,列举一二:
  • 1)ApplicationListenerDetector,在此阶段会把所有自定义的 ApplicationListener 先收录到 singletonNames 中,后续注册进容器
  • 2)AutowiredAnnotationBeanPostProcessor,基于 @Autowired @Value @Inject 注解将对应需要注入的元素(包括 Field Method)封装成对应的 InjectedElement,最后构造成对应的 InjectionMetadata,后续会试图对上述元素构造对应的 PropertyValues 用于属性填充
  • 3)CommonAnnotationBeanPostProcessor,与 AutowiredAnnotationBeanPostProcessor 类似,处理的是 @Resource 的注解

5)SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference

该方法的调用在 bean 实例化完成后、属性填充前,对于需要 循环依赖bean实例(是单例 & BeanFactory本身支持循环依赖 & 当前正在被循环依赖),此处会提前返回一个实例暴露给对应的 单例工厂(二级缓存)

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
	
		// ...

		// 对于 循环依赖 的单例此处现提前暴露实例给单例工厂(二级缓存)
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// ...

	}
  • 此处主要是为了解决 循环依赖,提前将实例暴露到单例工厂
  • 默认实现即返回实例本身,但在 AOP 的实现中,AbstractAutoProxyCreator 在此处返回对应的 代理对象

6)InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

该方法的调用在属性填充方法 AbstractAutowireCapableBeanFactory#populateBean 中,在确定要进行属性填充之前,此处会执行这组后处理器,判断是否跳过

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// 空处理 ...

		/**
		 * 此处是调用所有的 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
		 * 		但凡有返回 false,此处就 return 不继续注入了,目前的默认实现都是 true
		 */
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

		// ...
	}
  • 但凡有一个 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 返回 false,此处会放弃填充之前 return
  • 默认实现返回 true,目前未看到用途,猜测是可以注册在自定义的容器上下文中,进行自定义的属性注入

7)InstantiationAwareBeanPostProcessor#postProcessProperties

该方法的调用在属性填充方法 AbstractAutowireCapableBeanFactory#populateBean 中,在确定要进行属性填充后,便会执行所有 InstantiationAwareBeanPostProcessor#postProcessProperties,此处允许对属性填充所需的 PropertyValues 进行处理

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		
		// ...

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		/**
		 * 如果存在 InstantiationAwareBeanPostProcessor
		 * 则基于 InstantiationAwareBeanPostProcessor#postProcessProperties
		 * 		构造最终的 PropertyValues
		 */
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					// 有 postProcessPropertyValues 来兜底
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}
		}
		
		// 依赖校验...

		// PropertyValues 的属性绑定...
		
	}
  • PropertyValues 中对应属性的赋值最终委托是 BeanWrapper 实现的
  • 此处的实现类也不少,最最核心的就是 AutowiredAnnotationBeanPostProcessor:基于之前解析的 InjectedElement,进行属性赋值
  • 此处如果解析为 null,则继续交给 InstantiationAwareBeanPostProcessor#postProcessPropertyValues 方法,它的本质其实与前者一样,只是后者已被标注 @Deprecated,用来兜底,之后应该会被移除

8)BeanPostProcessor#postProcessBeforeInitialization

该方法的调用是在实例初始化 AbstractAutowireCapableBeanFactory#initializeBean 方法中,此处的 bean 已经完成实例化并且填充完属性,进入初始化阶段,在这之前,进行初始化前处理

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

		/**
		 * invokeAwareMethods:
		 * 执行 BeanNameAware BeanClassLoaderAware BeanFactoryAware 回调
		 */
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		/**
		 * 执行所有 BeanPostProcessor#postProcessBeforeInitialization:初始化前处理
		 */
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			/**
			 * 初始化:
			 * 1)InitializingBean#afterPropertiesSet
			 * 2)init-method 回调
			 */
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			
		}

		// ...

	}
  • 执行初始化操作之前调用,根据方法名也能看出来
  • 初始化操作主要有:1)InitializingBean#afterPropertiesSet 方法的执行 2)init-method 调用,比如 @Bean 注解指定、@PostConstruct 注解标注的方法
  • 列举几个代表实现:
  • 1)ApplicationContextAwareProcessor:执行各种 Aware 回调诸如 EnvironmentAware ApplicationContextAware
  • 2)BeanValidationPostProcessor:对当前 bean 的属性进行 validate 验证

9)BeanPostProcessor#postProcessAfterInitialization

该方法的调用在初始化相关操作之后,此时 bean实例 的初始化已完成,进行初始化后处理

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

		// ...

		try {
			/**
			 * 初始化:
			 * 1)InitializingBean#afterPropertiesSet
			 * 2)init-method 回调
			 */
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			
		}
		/**
		 * 执行所有 BeanPostProcessor#postProcessAfterInitialization:初始化后处理
		 */
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
  • bean实例 初始化操作完成后调用
  • 列举几个代表实现:
  • 1)AbstractAutoProxyCreator:大名鼎鼎的 AOP代理 一般就是在这个阶段实现,创建对应的代理对象后返回
  • 2)ApplicationListenerDetector:会把之前收录的自定义监听器 beanName,注册到容器中
  • 3)BeanValidationPostProcessor:再次对 bean实例 属性进行 validate 验证

总结

BeanPostProcessorSpring 暴露出来的核心拓展点,基于这些处理器,我们可以干涉到 bean实例 的个阶段生命周期,以实现各种定制化的需求

因此,明确清晰的了解各类处理器的执行时机是十分有必要的,本文的目的也是为了全面的梳理上述 BeanPostProcessor 的执行时机即功能,才能更加灵活的运用与拓展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值