返回

逆向 Spring 源码系列(九)- 确认构造方法

后端

前言

创建Bean实例之二,确定构造方法。上一篇讲解了如何对Bean进行依赖自动注入和实例化。本次继续对createBeanInstance方法进行解析。Spring是如何根据BeanDefinition确定其构造函数呢?这将涉及到我们之前提到的BeanPostProcessor。

determineConstructorsFromBeanPostProcessors

查看源码发现,该方法的代码不算复杂:

public static BeanWrapperImpl determineConstructorsFromBeanPostProcessors(
        Object bean, String beanName, BeanCreationException cause,
        InstantiationAwareBeanPostProcessorProvider instantiationAwareBeanPostProcessorProvider) {

    BeanPostProcessor bp = instantiationAwareBeanPostProcessorProvider.getEarlyBeanPostProcessor();
    if (bp != null && !beanName.startsWith(
            BeanFactoryPostProcessor.POST_PROCESSOR_BEAN_NAME_PREFIX)) {
        return bp.postProcessBeforeInstantiation(beanClass, beanName);
    }
    return null;
}

该方法从BeanPostProcessorProvider中获取所有的实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor,如果找到了,则直接调用其postProcessBeforeInstantiation方法。这个方法可以对Bean的实例化操作进行拦截,其返回值如果为null,说明要使用默认方式进行实例化,如果不为null,说明要使用新的方式进行实例化,Spring容器也会使用这种方式进行实例化。

BeanPostProcessor

BeanPostProcessor是一个非常重要的Spring扩展接口。BeanPostProcessor用于在BeanFactory已经完成bean实例化之后,为其进一步做一些个性化的增强或装饰。Spring IoC容器通过实现此接口可以干很多事情,例如:bean的初始化和销毁操作、AOP动态代理操作等。

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口。BeanPostProcessor包括14个方法,而InstantiationAwareBeanPostProcessor新增了两个方法,分别为:

  • postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在Spring IoC容器实例化Bean之前调用,可以返回一个BeanWrapper实例,如果返回null,表示要使用默认的方式创建Bean对象。
  • postProcessAfterInstantiation(Object bean, String beanName):在Spring IoC容器实例化Bean之后调用。

InstantiationAwareBeanPostProcessor接口,是Spring IoC容器感知bean实例化过程的一个标志。如果容器中含有实现了InstantiationAwareBeanPostProcessor接口的bean,那么Spring IoC容器在创建Bean的时候,就会首先调用其实现的postProcessBeforeInstantiation方法。如果postProcessBeforeInstantiation方法返回了null,那么Spring IoC容器将会按照默认方式创建Bean。如果postProcessBeforeInstantiation方法没有返回null,那么Spring IoC容器将会使用返回的BeanWrapper来创建Bean对象。

总结

本文讲解了Spring容器如何使用BeanPostProcessor来确认构造方法。Spring容器会首先从BeanPostProcessorProvider中获取所有的实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor,如果找到了,则直接调用其postProcessBeforeInstantiation方法。这个方法可以对Bean的实例化操作进行拦截,其返回值如果为null,说明要使用默认方式进行实例化,如果不为null,说明要使用新的方式进行实例化,Spring容器也会使用这种方式进行实例化。