Spring bean实例化

问题一:何时生成代理对象,尤其是事务的代理对象?
在两个地方可能生成代理对象:
一:InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation
二:BeanPostProcessor.postProcessAfterInitialization

生成事务的代理对象执行点:
(1)在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法执行
(2)SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference执行

问题二:循环依赖解决?
为何要三级缓存,而不是二级缓存?
好处:可扩展,修改提前暴露的对象
(把 aop 代理对象提前暴露出去,如果此时不暴露,循环依赖时,A 引用的对象不是B 的代理对象)

实现:三级缓存中存放的为ObjectFactory对象:singletonFactories,当循环依赖时获取缓存对象时,会执行工厂方法
ObjectFactory.getObject()-------->
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
进而获取AOP代理对象。

实现过程

三级缓存.png

SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法作用:
当存在循环依赖时,通过该回调方法获取AOP代理对象
(正常是在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法中生成代理对象的)。

具体过程

  1. 实例化对象后会放三级缓存
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    注意:放入缓存的是一个ObjectFactory实现,只有在循环依赖时,第二个对象获取第一个对象时,会执行ObjectFactory.getObject()方法实现(即getEarlyBeanReference)

获取缓存

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

AbstractAutowireCapableBeanFactory#getEarlyBeanReference

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return exposedObject;
}

AbstractAutoProxyCreator是SmartInstantiationAwareBeanPostProcessor的子类,
实现了getEarlyBeanReference用于生成 aop 代理对象的

@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (!this.earlyProxyReferences.contains(cacheKey)) {
        this.earlyProxyReferences.add(cacheKey);
    }
    return wrapIfNecessary(bean, beanName, cacheKey);
}

::wrapIfNecessary方法时生成 AOP代理对象::

  1. 正常生成 aop 代理对象是在postProcessAfterInitialization方法后,
    AbstractAutoProxyCreator#postProcessAfterInitialization实现
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

::postProcessAfterInitialization 中也使用了 wrapIfNecessary::
::不过如果由于在赋值时,为了解决循环依赖已经生成过AOP代理对象,这时不再生成代理::

一文告诉你Spring是如何利用三级缓存巧妙解决Bean的循环依赖问题的
Spring源码解析(十二)Spring扩展接口SmartInstantiationAwareBeanPostProcessor

BeanFactory

通过源代码看看创建一个Bean实例的具体执行流程:
[image:A568E489-2D7C-4E9B-9F0B-E1078E700F57-1306-000001E35047C75A/E453601C-514D-4406-9623-ACAB4F899BBD.png]

  1. bean的实例化通过BeanFactory接口实现:DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
  2. AbstractApplicationContext内部使用DefaultListableBeanFactory,且DefaultListableBeanFactory继承AbstractAutowireCapableBeanFactory,因此我们此处分析AbstractAutowireCapableBeanFactory即可。
  3. AbstractAutowireCapableBeanFactory的方法populateBean是主要实现,用于给bean实例填充数据

Spring创建Bean的流程

首先需要了解是Spring它创建Bean的流程,我把它的大致调用栈绘图如下:

Spring创建Bean的流程.png

对Bean的创建最为核心三个方法解释如下:
createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
populateBean:填充属性,这一步主要是对bean的依赖属性进行注入(@Autowired)
initializeBean:回到一些形如initMethod、InitializingBean等方法
一文告诉你Spring是如何利用三级缓存巧妙解决Bean的循环依赖问题

BeanFactory中bean的生命周期

当请求getBean时,即实例化bean对象。ApplicationContext是在refresh()方法里立即实例化了所有的bean。

BeanFactory中bean的生命周期.png

主要分为三阶段

  1. 实例化,创建Bean的过程,InstantiationAwareBeanPostProcessor作用于此
  2. 填充数据
  3. 初始化,BeanPostProcessor作用于此

阶段一:实例化

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()
此方法为核心方法,用于创建bean实例,填充bean属性,并执行后置方法

/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    RootBeanDefinition mbdToUse = mbd;

  //此处为特殊逻辑,如果有InstantiationAwareBeanPostProcessor实现生成代理对象,则直接返回,不会调下面的方法
    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //创建bean实例,调用populateBean填充属性
    try {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    }
}

resolveBeforeInstantiation 的功能为:
如果有InstantiationAwareBeanPostProcessor实现的postProcessBeforeInstantiation方法生成代理对象,则直接返回,不会调下面的方法

@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) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

注意:实例化之前执行InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation方法,当经过前置处理之后,返回的结果若不为空,那么会直接略过后续的Bean的创建而直接返回结果
::原因:resolveBeforeInstantiation只是针对有自定义的targetsource,因为自定义的targetsource不是spring的bean那么肯定不需要进行后续的一系列的实例化初始化。所以可以在resolveBeforeInstantiation直接进行proxy::

Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProcessor解析
Spring之InstantiationAwareBeanPostProcessor接口介绍 - 云+社区 - 腾讯云
Spring Aop之Target Source详解Java爱宝贝丶的博客-CSDN博客

阶段二:填充实例-populateBean实现

位于:AbstractAutowireCapableBeanFactory#populateBean

主要功能:

  1. 把Autowired注解的属性注入到实例中
  2. 执行实现了InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法修改实例

执行流程。如下:

  • 获取属性列表 pvs
  • 在属性被填充到 bean 前,应用后置处理自定义属性填充
  • 根据名称或类型解析相关依赖
  • 再次应用后置处理,用于动态修改属性列表 pvs 的内容
  • 将属性应用到 bean 对象中
    注意第3步,也就是根据名称或类型解析相关依赖(autowire)。该逻辑只会解析依赖,并不会将解析出的依赖立即注入到 bean 对象中。所有的属性值是在 applyPropertyValues 方法中统一被注入到 bean 对象中的。
    Spring IOC 容器源码分析 - 填充属性到 bean 原始对象_慕课手记
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    // 获取属性列表
    PropertyValues pvs = mbd.getPropertyValues();

    if (bw == null) {
        if (!pvs.isEmpty()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            return;
        }
    }

    boolean continueWithPropertyPopulation = true;
    /*
     * 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改 
     * bean 状态的机会。关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
     * 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过 
     * postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
     * 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现 
     * InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
     * 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
     */
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }

    /* 
     * 如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了
     * bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可
     */
    if (!continueWithPropertyPopulation) {
        return;
    }

    // 根据名称或类型注入依赖
    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);

    /*
     * 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
     * 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
     * 而是经过后置处理器修改后的内容
     */ 
    if (hasInstAwareBpps || needsDepCheck) {
        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) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    // 应用属性值到 bean 对象中
    applyPropertyValues(beanName, mbd, bw, pvs);

阶段三:初始化实例

初始化过程主要包含以下几个过程:

  1. 执行BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 接口实现
  2. 执行BeanPostProcessor.postProcessAfterInitialization:
  3. 执行InitializingBean接口的中afterPropertiesSet()方法(如果该实例实现)
  4. 执行实例init method
  5. 执行BeanPostProcessor.postProcessAfterInitialization

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

  invokeAwareMethods(beanName, bean);
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

你可能感兴趣的:(Spring bean实例化)