Bean的属性装配1: InstantiationAwareBeanPostProcessor

接上文,Bean的属性装配前2:SmartInstantiationAwareBeanPostProcessor

回到doCreateBean方法,把单例对象缓存到第三级缓存之后,开始对这个Bean进行属性填充,来到populateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
                final @Nullable Object[] args) throws BeanCreationException {
    // ...
    // Initialize the bean instance.
    // 开始初始化Bean
    Object exposedObject = bean;
    try {
        // 此处开始为一个Bean的属性赋值
        populateBean(beanName, mbd, instanceWrapper);
        // Bean的初始化过程,可见在属性赋值之后,后面会讨论这个过程
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException 
                && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, 
                "Initialization of bean failed", ex);
        }
    }
    // ...
}

/**
 *  为Bean的属性赋值的核心方法
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, 
            @Nullable BeanWrapper bw) {

    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, 
                "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // 给InstantiationAwareBeanPostProcessors一次机会在属性注入前修改Bean的状态
    // 具体通过调用postProcessAfterInstantiation方法,
    // 如果调用返回false,表示不必继续进行依赖注入,直接返回
    boolean continueWithPropertyPopulation = true;

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp 
                        = (InstantiationAwareBeanPostProcessor) bp;
                // 从这里可以得到结论,一旦对某个bean进行属性装配的时候,执行此处的后置回调方法
                // 一旦某个回调返回false,那么continueWithPropertyPopulation被赋值为false
                // 后续Spring就不会为这个bean进行属性填充
                if (!ibp.postProcessAfterInstantiation(
                                        bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    // 如果InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation返回false
    // 则不进行后续的属性填充操作,包括自动装配和@Autowired属性注入
    if (!continueWithPropertyPopulation) {
        return;
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
    // 根据Bean配置的自动装配模式完成注入,默认是0,即不走以下逻辑
    // 如果设置了相关的依赖装配方式,会遍历Bean中的属性
    // 根据类型或名称来完成相应注入,无需额外配置
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME 
            || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // 根据名称自动装配
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // 根据类型自动装配
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }

        pvs = newPvs;
    }

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

    if (hasInstAwareBpps || needsDepCheck) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        PropertyDescriptor[] filteredPds 
            = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            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属性,
            // 需要确保所有依赖的Bean先完成初始化
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    if (pvs != null) {
        // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

在这里,我们又看到了熟悉的InstantiationAwareBeanPostProcessor后置处理器,在Bean的实例化过程中,Spring借助它的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation在一个Bean实例化之前回调判断是否需要为Bean生成代理对象(Bean实例化1:InstantiationAwareBeanPostProcessor),此处Spring则是利用它的InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation回调处理,简单的来看下这个借口的定义,它继承了BeanPostProcessor

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 
            throws BeansException {
        return null;
    }

    /**
     * Perform operations after the bean has been instantiated, via a constructor or factory method,
     * but before Spring property population (from explicit properties or autowiring) occurs.
     * <p>This is the ideal callback for performing custom field injection on the given bean
     * instance, right before Spring's autowiring kicks in.
     * <p>The default implementation returns {@code true}.
     *
     * 在一个bean通过构造器或者工厂方法实例化之后,在Spring为这个Bean装配属性之前调用
     * 这是在Spring自动注入属性之前,为指定bean进行自定义属性注入的最理想回调时机
     * 结合populateBean属性装配方法,可以看到,当这个方法返回false的时候,
     * 其实就是告诉Spring这个bean不需要进行属性装配
     */
    default boolean postProcessAfterInstantiation(Object bean, String beanName) 
            throws BeansException {
        return true;
     }

    @Nullable
    default PropertyValues postProcessPropertyValues(PropertyValues pvs, 
            PropertyDescriptor[] pds, Object bean, String beanName) 
            throws BeansException {

        return pvs;
    }
}

总结:
Spring在为bean进行属性填充的时候,提供了一个扩展点InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation,利用此扩展点,可以决定某个bean是否交由Spring进行属性填充

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。