Spring中特殊的后置处理器/AOP的基础——InstantiationAwareBeanPostProcessor

原创
2020/05/05 18:06
阅读数 1.4K

参考该文档前,请先参考Spring中的BeanPostProcessor——Bean后置处理器

InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

1、实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中。

2、初始化:执行Bean的Init-method方法。

InstantiationAwareBeanPostProcessor继承于BeanPostProcessor,并且在BeanPostProcessor的基础之上,扩展了3个方法。

并且它与以往的BeanPostProcessor不同,他的执行时间并不是Bean的初始化前后,而是Bean的实例化前后。

InstantiationAwareBeanPostProcessor的作用是为Spring中的Bean生成代理对象,AOP就是基于InstantiationAwareBeanPostProcessor实现的

InstantiationAwareBeanPostProcessor 的源代码如下

代码示例 

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	 * Bean 实例化之前执行的方法
	 */
	Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

	/**
	 * Bean 实例化之后执行的方法
	 */
	boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

	/**
	 * Bean 的成员变量操作方法
	 */
	PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

}

InstantiationAwareBeanPostProcessor在Spring中执行的地方为实例化Bean前后,也就是AbstractAutowireCapableBeanFactory的createBean中执行doCreateBean的前后

代码示例 

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   
	...省略代码

   try {
      // 给beanPostProcessor一个返回代理而不是目标bean实例的机会,在这里执行了InstantiationAwareBeanPostProcessor的方法。注意:这里就是实现AOP的关键,在学习AOP源码的时候我们还会进行分析
      // 如果返回值不为空,说明生成成了此BeanName的代理,直接返回代理对象
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   // 执行创建Bean实例的方法
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   if (logger.isDebugEnabled()) {
      logger.debug("Finished creating instance of bean '" + beanName + "'");
   }
   return beanInstance;
}

AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation方法

代码示例 

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   // 通过beforeInstantiationResolved字段判断Bean是否有需要在实例化之前执行的操作,如果beforeInstantiationResolved还没有设置或者是false,将会进入方法体
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // 判断是否有注册过InstantiationAwareBeanPostProcessor类型的处理器处理Bean
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            // 执行所有InstantiationAwareBeanPostProcessor的postProcessorsBeforeInstantiation方法,该方法用于Bean实例化之前的操作
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            if (bean != null) {
               // 如果有bean返回,说明Bean有改动,之后将执行所有InstantiationAwareBeanPostProcessor的postProcessorsAfterInitialization方法,该方法用于Bean初始化之后的操作(中间的实例化之后和初始化之前的方法都不会执行了)
               // 此处用于产生Bean的代理
               // 此处为何判断有Bean返回就执行Bean初始化之后的操作呢?,因为有Bean返回,表示Bean已经实例化完成,并且InstantiationAwareBeanPostProcessor的实现类中应该已经完成了Bean初始化的动作,因此这里直接执行了用于Bean初始化之后的方法
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
	  // 重新设置beforeInstantiationResolved 字段
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}


protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   // 获取所有后置处理器
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
	  // 将InstantiationAwareBeanPostProcessor类型的后置处理器筛选出来
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         // 执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
         // 如果我们有需要自己定义了InstantiationAwareBeanPostProcessor的实现类,postProcessBeforeInstantiation默认都要返回null,这就是原因
         // 参考AutowiredAnnotationBeanPostProcessor的父类InstantiationAwareBeanPostProcessorAdapter,或CommonAnnotationBeanPostProcessor的源码
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         // 当返回结果不为null表明InstantiationAwareBeanPostProcessor生成了代理类,直接返回
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}


@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {
   Object result = existingBean;
   // 执行所有的InstantiationAwareBeanPostProcessor后置处理器的postProcessorsAfterInitialization方法,直到全部执行完,或其中有返回结果为null的。
   // 如果我们有需要自己定义了InstantiationAwareBeanPostProcessor的实现类,postProcessAfterInitialization或者postProcessBeforeInitialization默认都要返回入参bean,这里就是原因
   // 参考AutowiredAnnotationBeanPostProcessor的父类InstantiationAwareBeanPostProcessorAdapter,或CommonAnnotationBeanPostProcessor的源码
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      result = beanProcessor.postProcessAfterInitialization(result, beanName);
      if (result == null) {
         return result;
      }
   }
   return result;
}

到此,Bean实例化前InstantiationAwareBeanPostProcessor的执行到此结束,接下来是Bean实例化之后InstantiationAwareBeanPostProcessor的执行

我们直接跳跃到doCreateBean方法中调用的populateBean方法,该方法用于Bean实例化之后,对Bean进行依赖注入的操作

代码示例 

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
 
    ...省略代码

    // 用于决定是否进行依赖注入的标志位
	boolean continueWithPropertyPopulation = true;

	// 在此处判断BeanFactory中是否存在InstantiationAwareBeanPostProcessor
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		
   		for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 判断后置处理器是否为InstantiationAwareBeanPostProcessor类型的
      		if (bp instanceof InstantiationAwareBeanPostProcessor) {
         		InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法,并根据返回值,决定是否执行后续的依赖注入
				// 如果postProcessAfterInstantiation返回false那么当前Bean将不会执行依赖注入,如果返回true,就会执行依赖注入,因此我们在使用postProcessAfterInstantiation方法时要注意自己的返回值
         		if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            		continueWithPropertyPopulation = false;
            		break;
         		}
      		}
   		}
	}

	if (!continueWithPropertyPopulation) {
   		return;
	}
 
    // 容器是否注册了InstantiationAwareBeanPostProcessor
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否进行依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
 
    if (hasInstAwareBpps || needsDepCheck) {
        // 过滤出所有需要进行依赖检查的属性编辑器
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                // 这里执行所有的InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    // 这里再次调用了前面在Spring上下文初始化的时候注入的几个重要的处理器,用来完成Bean的依赖注入
                    // 其中AutowiredAnnotationBeanPostProcessor这个后置处理器完成了Bean的 @Autowired注解和 @Value注解的解析
                    // 其中CommonAnnotationBeanPostProcessor这个后置处理器完成了Bean的@Resource直接的解析
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 通过postProcessPropertyValues方法填充Bean中的依赖注入Bean
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
         
        ...代码省略
}

我们通过实践来体验下InstantiationAwareBeanPostProcessor后置处理器的功能,利用它生成一个代理类,简单模拟一个AOP

创建一个Spring的配置类,配置下简单的包扫描即可

代码示例 

@Configuration()
@ComponentScan("com.spring.iocTest.beanpostprocessor")
public class SpringBeanConfig{

}

创建一个被代理的Bean

代码示例 

@Component("testBean")
public class TestBean {

    private String desc = "Hello World";

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public void method(){
        System.out.println(desc);
    }

}

创建一个代理类,我们不做什么特殊操作,知识在被代理对象的方法执行前后进行一些打印操作

代码示例 

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;


public class TestBeanProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("目标方法前:" + method+"\n");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("目标方法后:" + method+"\n");
        return object;
    }
}

创建一个InstantiationAwareBeanPostProcessor 的实现类,postProcessBeforeInstantiation方法用于创建代理类返回,其他的方法则只进行一些适配操作和打印输出即可

代码示例 

import net.sf.cglib.proxy.Enhancer;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;

import java.beans.PropertyDescriptor;


@Component
public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass==TestBean.class){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanClass);
            enhancer.setCallback(new TestBeanProxy());
            TestBean testBean = (TestBean)enhancer.create();
            return testBean;
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.print("beanName:"+beanName+"执行..postProcessAfterInstantiation\n");
        return false;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.print("beanName:"+beanName+"执行..postProcessPropertyValues\n");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.print("beanName:"+beanName+"执行..postProcessBeforeInitialization\n");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.print("beanName:"+beanName+"执行..postProcessAfterInitialization\n");
        return bean;
    }
}

测试类

代码示例 

public class SpringToTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringBeanConfig.class);
        TestBean bean = (TestBean)applicationContext.getBean("testBean");
        bean.method();

    }
}

我们看下,在测试类方法执行后,使用InstantiationAwareBeanPostProcessor 和未使用的区别

这是使用InstantiationAwareBeanPostProcessor 返回代理时

不使用InstantiationAwareBeanPostProcessor时testBean的状态

很明显,上面使用了InstantiationAwareBeanPostProcessor后返回了代理对象TestBeanProxy ,而不是TestBean。通过这个InstantiationAwareBeanPostProcessor的实践,我们也清楚了AOP的实现基础了,后续分析AOP的源码时,也就相对轻松了。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部