06-spring InstantiationAwareBeanPostProcessor接口

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/my_momo_csdn/article/details/91593937

InstantiationAwareBeanPostProcessor

  • InstantiationAwareBeanPostProcessor是BeanPostProcessor接口的一个子接口,除了继承了BeanPostProcessor的
    2个环绕处理方法之外,自己还定义了3个方法,继承自BeanPostProcessor的方法是作用于Bean初始化前后,自己定义的2个方法
    作用于Bean的实例化前后,注意实例化在初始化之前,另外还有一个方法用于赋值,详情如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	 *  1.实例化之前执行
	 */
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	/**
	 *  2.实例化之后执行
	 */
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	/**
	 *  3.赋值操作,比如依赖注入时,@Autowire和@Value注解的值的注入就是基于该方法
	 */
	@Nullable
	default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
		return pvs;
	}
}



public interface BeanPostProcessor {

	/**
	 *  1.初始化之前执行
	 */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	/**
	 *  2.初始化之后执行
	 */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
  • 这里我们可以知道InstantiationAwareBeanPostProcessor和他的父接口BeanPostProcessor各代表了一种扩展点,前者是实例化前后
    调用,后置是初始化前后调用,这对应着不同的bean的生命周期阶段。

一、调用时机

  • 我们首先还是看看InstantiationAwareBeanPostProcessor接口自己定义的三个方法的调用时机,我们通过bean的生命周期源码的方法跟进,
    跟进到AbstractAutowireCapableBeanFactory#createBean()#line 462
    (可以参考03-spring BeanPostProcessor文章中的BeanPostProcessor方法的调用时机小节)

  • AbstractAutowireCapableBeanFactory#createBean()#line 462。这里我们看到注释,意思是给BeanPostProcessors一个机会返回一个目
    标bean的代理,如果返回了的话,那么就直接return了

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

		//---省略----

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			//1.给BeanPostProcessors一个机会返回一个目标bean的代理
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			//2.如果给一个机会,BeanPostProcessors把握了机会成功返回了一个bean,那么就直接return
			if (bean != null) {
				return bean;
			}
		}
		
		//---省略----
		//3.如果给一个机会,BeanPostProcessors没有把握不能返回了一个bean,那么就走创建流程
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		//---省略----
	}
  • AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation()#line 1033。前面给的一个机会就在这个方法里面执行,这里很有意思,但是第
    一次看会很糊涂,而且本文我写的也不是非常详细,具体在最后给出一个分析bean创建总体流程的文章才能说明白。这里的意思是先执行InstantiationAwareBeanPostProcessor
    接口的postProcessBeforeInstantiation方法,来看能不能返回一个bean(从前面的注释看出这里是尝试获取一个目标bean的代理),如果获取到了,就直接
    执行BeanPostProcessor#postProcessAfterInitialization方法,注意执行的是它的父类的后置方法,而不是自己的后置方法,也就是这里实际上跳过了
    BeanPostProcessor的前置方法和InstantiationAwareBeanPostProcessor自身的后置方法以及赋值方法,我们之前理解的bean的生
    命周期里面一般是下面这样的(只包含部分核心流程):
InstantiationAwareBeanPostProcessor前置方法执行->InstantiationAwareBeanPostProcessor后置方法执行->InstantiationAwareBeanPostProcessor赋值方法执行->BeanPostProcessor前置方法执行->初始化->BeanPostProcessor后置方法执行

在这里流程是下面这样的。也就是说这样的流程,BeanPostProcessor的前置方法根本没有执行,并且跳过了InstantiationAwareBeanPostProcessor自身的赋值方法和后置方法。

InstantiationAwareBeanPostProcessor前置方法执行返回bean成功->BeanPostProcessor后置方法执行->bean创建成功
  • 这里第一次看估计绕进去出不来,后续参考08-spring Bean生命周期详细图解
    @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.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//1.先调用InstantiationAwareBeanPostProcessor的前置方法,尝试获取一个bean(实际上是目标bean的一个代理)
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
					//2.获取一个bean成功,那么直接执行BeanPostProcessor的后置处理方法,相当于将InstantiationAwareBeanPostProcessor的
					//后置处理方法,赋值方法,以及BeanPostProcessor的前置处理方法都跳过了,会直接返回bean,代表创建bean结束
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

    //InstantiationAwareBeanPostProcessor前置方法执行
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}
	
	 //BeanPostProcessor后置方法执行
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

二、实现类

2.1 AutowiredAnnotationBeanPostProcessor

  • 在前面我们分析过,AutowiredAnnotationBeanPostProcessor是InstantiationAwareBeanPostProcessor接口的主要实现类,其支持的功能也是我们使用最多的。前面
    有一篇文章来介绍AutowiredAnnotationBeanPostProcessor,详情参考04-spring AutowiredAnnotationBeanPostProcessor

2.2 AspectJAwareAdvisorAutoProxyCreator

  • AspectJAwareAdvisorAutoProxyCreator是AOP的核心类,我们在前面的注释里说到,在InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法里面尝试返回一个
    目标bean的动态代理,而AOP底层就是动态代理,这里就是AOP的切入点。思路是在这里通过AOP的核心类返回了一个bean的动态代理对象而不是真正的去创建目标bean,这里我们不对
    AspectJAwareAdvisorAutoProxyCreator做深入的分析,放到后面AOP的专门文章中分析。

三、小结

  • 本文我们主要分析了InstantiationAwareBeanPostProcessor接口的结构,然后从bean的整个生命周期分析接口方法的调用时机,并区别其自己的方法和继承自BeanPostProcessor接口的方法
    之间的区别。最后我们回到之前分析过的AutowiredAnnotationBeanPostProcessor类,分析接口方法在这个类中所起的作用。
  • InstantiationAwareBeanPostProcessor接口主要是在Spring框架中使用,通过分析我们可以更好的了解bean的生命周期和基于该接口实现的注解功能及其对应原理。

四、参考

猜你喜欢

转载自blog.csdn.net/my_momo_csdn/article/details/91593937