Spring源码阅读----Spring IoC之finishBeanFactoryInitialization及Spring 如何解决循环依赖

概述

前面我们从registerBeanPostProcessors方法解析的时候,已经提到了finishBeanFactoryInitialization方法。我们先越过中间的消息资源初始化以及事件监听的部分,来解析一下finishBeanFactoryInitialization这个方法,因为我们从前面已经知道Spring IoC最重要部分就在于:obtainFreshBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors 和finishBeanFactoryInitialization 这四个方法,而finishBeanFactoryInitialization 又是Spring IoC的核心
在finishBeanFactoryInitialization 方法里,会实例化所有剩余的非懒加载单例 bean(包括一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,以及其他的非懒加载单例 bean) , 之前注册了的BeanPostProcessor 实现类也是在这里被调用执行其方法的。

finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // Initialize conversion service for this context.
        // 为上下文初始化转换服务
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // Register a default embedded value resolver if no bean post-processor
        // (such as a PropertyPlaceholderConfigurer bean) registered any before:
        // at this point, primarily for resolution in annotation attribute values.
        // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        // 获取LoadTimeWeaverAware类型的bean名称
        // 遍历初始化LoadTimeWeaverAware Bean实例对象
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        // Allow for caching all bean definition metadata, not expecting further changes.
        // 冻结配置,允许缓存所有bean定义元数据,所有bean定义不会被修改或进一步后处理
        beanFactory.freezeConfiguration();

        // Instantiate all remaining (non-lazy-init) singletons.
        //注释1. 实例化所有剩余(非懒加载)单例对象
        beanFactory.preInstantiateSingletons();
    }

执行步骤按方法中的注释往下走,比较清晰,最后到达最后一步实例化。具体来看最后一步的实例化步骤。

注释1. 实例化所有剩余(非懒加载)单例对象 (见源码解析1)
【源码解析1】 beanFactory.preInstantiateSingletons
我们知道beanFactory是DefaultListableBeanFactory类型,所以preInstantiateSingletons方法源码如下:

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        //创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {

            //注释1. 获取beanName对应的MergedBeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

            // 判断bd这个Bean实例:不是抽象类 && 是单例 && 不是懒加载
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

                //注释2. 判断beanName对应的bean是否为FactoryBean
                if (isFactoryBean(beanName)) {

                    //注释2-1. getBean('&'+beanName)将得到bean本身
                    //通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        //判断它是不是FactoryBean类型,然后获取FactoryBean实例
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;

                        // 急切初始化标识
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }

                        //注释2-2. 如果需急切初始化,则通过getBean(beanName)获取bean实例
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    //注释2-3 如果beanName对应的bean不是FactoryBean,只是普通Bean,通过getBean(beanName)获取bean实例
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        // 注释3. 遍历beanNames,触发post-initialization 回调
        for (String beanName : beanNames) {

            // 获取beanName对应的单例bean实例
            Object singletonInstance = getSingleton(beanName);

            //判断singletonInstance是否实现了SmartInitializingSingleton接口
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;

                    //触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

整个流程按注释顺序下来,比较清晰。这里出现了两个比较重要的名称:MergedBeanDefinition 和FactoryBean后面一一解释。
其中需要解析的部分如下:
注释1. 获取beanName对应的MergedBeanDefinition (见源码解析2)
注释2. 判断beanName对应的bean是否为FactoryBean,isFactoryBean方法放最后解释。 (见源码解析4)
注释2-2 、注释2-3 都为getBean(beanName)获取bean实例,前者为FactoryBean实例,后者为普通bean实例。getBean是一个非常重要的方法,将在后边详细解析。

注释3. 遍历 beanNames,触发所有 SmartInitializingSingleton 的后初始化回调,这是 Spring 提供的一个扩展点,在所有非懒加载单例实例化结束后调用

【源码解析2】 AbstractBeanFactory类中的getMergedLocalBeanDefinition方法:

    // 方法1
    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {

        // Quick check on the concurrent map first, with minimal locking.
        //先检查beanName对应的MergedBeanDefinition是否存在于缓存中
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null) {

            // 存在,则返回缓存
            return mbd;
        }

        //不存在,则通过getBeanDefinition获取BeanDefinition,然后通过beanName、BeanDefinition 获取MergedBeanDefinition
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }

    // 方法2 它只是个适配器,交给方法3执行
    protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
            throws BeanDefinitionStoreException {

        return getMergedBeanDefinition(beanName, bd, null);
    }

    // 方法3,核心方法
    protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {

         // 加同步锁
        synchronized (this.mergedBeanDefinitions) {

            // 定义一个mbd返回值,用于存储bd的MergedBeanDefinition
            RootBeanDefinition mbd = null;

            // Check with full lock now in order to enforce the same merged instance.
            if (containingBd == null) {

                // 检查beanName对应的MergedBeanDefinition是否存在于缓存中
                mbd = this.mergedBeanDefinitions.get(beanName);
            }

            // 如果beanName对应的MergedBeanDefinition不存在于缓存中
            if (mbd == null) {

                //如果bd的parentName为空
                if (bd.getParentName() == null) {
                    // Use copy of given root bean definition.
                    //如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        //否则,将bd作为参数,创建一个RootBeanDefinition对象
                        mbd = new RootBeanDefinition(bd);
                    }
                }
                else {
                    // Child bean definition: needs to be merged with parent.
                    //注释1. 若bd的parentName不为空,bd存在父定义,需要与父定义合并
                    BeanDefinition pbd;
                    try {

                        //注释1-1. 获取父定义的beanName
                        String parentBeanName = transformedBeanName(bd.getParentName());

                        //注释1-2. 如果父定义的beanName与该bean的beanName不同
                        if (!beanName.equals(parentBeanName)) {
                            //注释1-2-1. 获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,即向上获取合并定义...)
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            //注释1-2-2. 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory
                            //只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                //注释1-2-3. 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }
                            else {
                                //注释1-2-4. 如果父BeanFactory不是ConfigurableBeanFactory,则抛异常
                                throw new NoSuchBeanDefinitionException(parentBeanName,
                                        "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                        "': cannot be resolved without an AbstractBeanFactory parent");
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                    }
                    // Deep copy with overridden values.
                    //注释1-3. 深拷贝 覆盖值
                    //使用父定义pbd构建一个新的RootBeanDefinition对象
                    mbd = new RootBeanDefinition(pbd);

                    //使用bd覆盖父定义
                    mbd.overrideFrom(bd);
                }

                // Set default singleton scope, if not configured before.
                if (!StringUtils.hasLength(mbd.getScope())) {
                    //注释2. 如果没有配置scope,则设置成默认的singleton
                    mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
                }

                // A bean contained in a non-singleton bean cannot be a singleton itself.
                // Let's correct this on the fly here, since this might be the result of
                // parent-child merging for the outer bean, in which case the original inner bean
                // definition will not have inherited the merged outer bean's singleton status.
                if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    //注释3. 如果containingBd不为空,
                    //并且 containingBd不为singleton ,
                    //并且 mbd为singleton,则将mdb的scope设置为containingBd的scope
                    mbd.setScope(containingBd.getScope());
                }

                // Cache the merged bean definition for the time being
                // (it might still get re-merged later on in order to pick up metadata changes)
                if (containingBd == null && isCacheBeanMetadata()) {
                    //注释4. 将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }

            //注释5. 返回MergedBeanDefinition
            return mbd;
        }
    }

    //方法4. 用户获取父类等上层的MergedBeanDefinition
    public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {

                // 获取真正的beanName(解析别名)
        String beanName = transformedBeanName(name);
        // Efficiently check whether bean definition exists in this factory.
        // 如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory
        if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {

            // 则调用父BeanFactory去获取beanName的MergedBeanDefinition
            return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
        }

        // Resolve merged bean definition locally.
        // 在当前BeanFactory中解析beanName的MergedBeanDefinition
        return getMergedLocalBeanDefinition(beanName);
    }

这里出现了一个新名称父 BeanFactory,后面一一解释。
注释1-1. 获取父定义的beanName,使用了transformedBeanName方法来获取 (见源码解析3)
注释1-2-1. 获取父定义的MergedBeanDefinition(见源码解析1中的方法4)
注释1-3. 深拷贝 覆盖值,合并操作,产生MergedBeanDefinition
注释4. 将beanName与mbd放到mergedBeanDefinitions缓存,所以方法1执行的时候,有缓存就会获取缓存。

【源码解析3】 transformedBeanName

    // AbstractBeanFactory类中的transformedBeanName方法
    protected String transformedBeanName(String name) {
                //注释1将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名
        return canonicalName(BeanFactoryUtils.transformedBeanName(name));
    }

    // BeanFactoryUtils类中的transformedBeanName方法
    public static String transformedBeanName(String name) {
        Assert.notNull(name, "'name' must not be null");
        if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
            return name;
        }
        return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
            do {
                beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
            }
            while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
            return beanName;
        });
    }

    // SimpleAliasRegistry类中的canonicalName方法
    public String canonicalName(String name) {
        String canonicalName = name;
        // Handle aliasing...
        String resolvedName;
        do {
            resolvedName = this.aliasMap.get(canonicalName);
            if (resolvedName != null) {
                canonicalName = resolvedName;
            }
        }
        while (resolvedName != null);
        return canonicalName;
    }

SimpleAliasRegistry为AbstractBeanFactory父类,canonicalName调用的是SimpleAliasRegistry中的方法。FACTORY_BEAN_PREFIX为'&'符,将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。

好了,我们先来把前面遇到的新名称解释一下:
MergedBeanDefinition
MergedBeanDefinition 通过字面意思,可以看出来是 合并的Bean定义,在执行过程中,我们遇到了一个bean定义,它可能有父定义等情况,有以下几种情况:

  • 该 BeanDefinition 存在 “父定义”:首先使用 “父定义” 的参数构建一个 RootBeanDefinition,然后再使用该 BeanDefinition 的参数来进行覆盖。
  • 该 BeanDefinition 不存在 “父定义”,并且该 BeanDefinition 的类型是 RootBeanDefinition:直接返回该 RootBeanDefinition 的一个克隆。
  • 该 BeanDefinition 不存在 “父定义”,但是该 BeanDefinition 的类型不是 RootBeanDefinition:使用该 BeanDefinition 的参数构建一个 RootBeanDefinition

BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition 或 ScannedGenericBeanDefinition,但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。

如果我们使用 XML 配置来注册 bean,则该 bean 定义会被封装成:GenericBeanDefinition;如果我们使用注解的方式来注册 bean,也就是<context:component-scan /> 或 @Compoment,则该 bean 定义会被封装成 ScannedGenericBeanDefinition

FactoryBean
通常初学者比较容易被BeanFactory和FactoryBean搅浑,其实很容易区分,前面我们已经介绍过BeanFactory接口,是IOC容器或对象工厂,它是Spring IOC的基础,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理。

一般情况下,Spring通过反射机制利用bean的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
FactoryBean,是一种特殊的bean, 它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。

为了区分 “FactoryBean” 和 “FactoryBean 创建的 bean 实例”,Spring 使用了 “&” 前缀。Spring里有很多类实现了FactoryBean,那我们找一个 beanName 为 gson的,则 getBean("gson") 获得的是 MapperFactoryBean 通过 getObject() 方法创建的Gson bean 实例;而 getBean("&gson") 获得的是 GsonFactoryBean本身。

父BeanFactory
在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。最常见的例子就是:Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

【源码解析4】 执行的该isFactoryBean方法,在AbstractBeanFactory类中

    // 方法1
    public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {

        // 转换beanName,获取真正的beanName(去掉&前缀、解析别名)
        String beanName = transformedBeanName(name);

        //注释1.  获取beanName对应的单例bean实例
        Object beanInstance = getSingleton(beanName, false);
        if (beanInstance != null) {

            //beanInstance存在,则直接判断其类型是否为FactoryBean
            return (beanInstance instanceof FactoryBean);
        }

        // No singleton instance found -> check bean definition.
        if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
            // No bean definition found in this factory -> delegate to parent.
            // 如果缓存中不存在此beanName 
            // 并且父beanFactory是ConfigurableBeanFactory,
            // 则调用父BeanFactory判断是否为FactoryBean
            return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
        }

        //注释2. 通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
        return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
    }

    // 方法2
    protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
        // 拿到beanName对应的Bean实例的类型
        Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
        return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
    }

注释1. 获取beanName对应的单例bean实例(见源码解析5)
注释2. 通过 MergedBeanDefinition 来检查 beanName 对应的 bean 是否为 FactoryBean。首先通过 getMergedLocalBeanDefinition 方法获取 beanName 的 MergedBeanDefinition,接着调用 isFactoryBean 来检查 beanName 对应的 bean 是否为 FactoryBean。
这里的isFactoryBean 方法为上面方法2,其调用了predictBeanType方法来获取beanName对应的Bean实例的类型(见源码解析6),然后通过isAssignableFrom方法来判断beanType是否与FactoryBean接口类型相同。

【源码解析5】 getSingleton方法,在DefaultSingletonBeanRegistry类中,

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {

        //从单例对象缓存中获取beanName对应的单例对象
        Object singletonObject = this.singletonObjects.get(beanName);
        // 检查缓存中是否存在实例
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

            // 加锁进行操作,公共变量都需要加锁操作,避免多线程并发修改
            synchronized (this.singletonObjects) {
                // 从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为
                //earlySingletonObjects里的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
                singletonObject = this.earlySingletonObjects.get(beanName);

                //如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
                if (singletonObject == null && allowEarlyReference) {

                    // 从单例工厂缓存中获取beanName的单例工厂
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);

                    if (singletonFactory != null) {

                        //如果存在单例对象工厂,则通过工厂创建一个单例对象
                        singletonObject = singletonFactory.getObject();

                        //将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        //返回单例对象
        return singletonObject;
    }

主要操作步骤就是检查下我们要拿的 bean 实例是否存在于缓存中,如果有就返回缓存中的 bean 实例,否则就返回 null。

Spring 解决循环依赖的核心就是依赖这里的代码,所以它是一段比较重要的代码。

解决循环依赖逻辑:使用构造函数创建一个 “不完整” 的 bean 实例(之所以说不完整,是因为此时该 bean 实例还未初始化),并且提前曝光该 bean 实例的 ObjectFactory(提前曝光就是将 ObjectFactory 放到 singletonFactories 缓存),通过 ObjectFactory 我们可以拿到该 bean 实例的引用,如果出现循环引用,我们可以通过缓存中的 ObjectFactory 来拿到 bean 实例,从而避免出现循环引用导致的死循环。这边通过缓存中的 ObjectFactory 拿到的 bean 实例虽然拿到的是 “不完整” 的 bean 实例,但是由于是单例,所以后续初始化完成后,该 bean 实例的引用地址并不会变,所以最终我们看到的还是完整 bean 实例。

这段解决逻辑涉及到了后面的一些内容,所以可能会看的不是很理解,可以先有个印象,等把创建 bean 实例都看完了,再回过头来看,可能会好理解一点。

另外这个代码块中引进了4个重要缓存:

  • singletonObjects 缓存:beanName -> 单例 bean 对象。
  • earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
  • singletonFactories 缓存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。

singletonObjects、earlySingletonObjects、singletonFactories 在这边构成了一个类似于 “三级缓存” 的概念。

【源码解析6】 predictBeanType方法,在AbstractAutowireCapableBeanFactory类中

    @Override
    @Nullable
    protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {

        //获取beanName的类型
        Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);

        // Apply SmartInstantiationAwareBeanPostProcessors to predict the
        // eventual type after a before-instantiation shortcut.
        // 2.应用SmartInstantiationAwareBeanPostProcessors后置处理器,来预测实例化的最终类型,
        // SmartInstantiationAwareBeanPostProcessors继承了InstantiationAwareBeanPostProcessor,
        // InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法可以改变Bean实例的类型,
        // 而SmartInstantiationAwareBeanPostProcessors的predictBeanType方法可以预测这个类型
        if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;

                    //调用predictBeanType方法
                    Class<?> predicted = ibp.predictBeanType(targetType, beanName);
                    if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
                            FactoryBean.class.isAssignableFrom(predicted))) {
                        //如果predicted不为空,并且
                        //(typesToMatch长度不为1或typesToMatch[0]不为FactoryBean.class或predicted是FactoryBean本身、子类或子接口)
                        //返回predicted
                        return predicted;
                    }
                }
            }
        }

        //返回beanName的类型
        return targetType;
    }

这边执行的是 AbstractAutowireCapableBeanFactory 里的方法,而不是 AbstractBeanFactory 里的方法。
通过前面的介绍,我们知道创建的 BeanFactory 为 DefaultListableBeanFactory,而 DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory,因此这边会走 AbstractAutowireCapableBeanFactory 的重写方法。

总结

通过finishBeanFactoryInitialization方法的解析,知道这里是如何创建 bean 实例的,以及bean实例化之前的一些准备操作。主要是引入了 FactoryBean 这一特殊的 bean,获取 BeanDefinition 的 MergedBeanDefinition,最后将 BeanDefinition 统一转换成 RootBeanDefinition。

中间还学习了Spring如何解决循环依赖的问题,是通过缓存。
Spring 中大量使用了本地缓存,基本上通过名字和注释就能理解缓存的作用了。
这里用到的几个缓存:

  • mergedBeanDefinitions 缓存:beanName -> 合并的 bean 定义。
  • beanDefinitionMap 缓存:beanName -> BeanDefinition。
  • singletonObjects 缓存:beanName -> 单例 bean 对象。
  • earlySingletonObjects 缓存:beanName -> 单例 bean 对象,该缓存存放的是早期单例 bean 对象,可以理解成还未进行属性填充、初始化。
  • singletonFactories 缓存:beanName -> ObjectFactory。
  • singletonsCurrentlyInCreation 缓存:当前正在创建单例 bean 对象的 beanName 集合。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容