【spring 4.3.7】Spring IoC源码学习:finishBeanFactoryInitialization() 详解

前言

在介绍了 obtainFreshBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors 三个重要方法后,我们终于来到了最后一个重要方法:finishBeanFactoryInitialization。finishBeanFactoryInitialization 是这四个方法中最复杂也是最重要的,是整个 Spring IoC 核心中的核心。

概述

finishBeanFactoryInitialization()方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

实例化的过程各种BeanPostProcessor开始起作用。

在IoC BeanFactory容器初始化过程中,默认是对BeanDefinition的定位,载入,解析和注册,此时的依赖注入并没有发生,只有在第一次向容器索要Bean时,第一次执行getBean调用时才会完成依赖注入;而我们又知道,ApplicationContext spring bean的加载策略,默认提前实例化单例且是非lazy的bean,也就是说当我们在业务代码中第一次调用getBean(A),如果A是单例且没有lazy标识,那么此时得到的实例是提前实例化的,只是从缓存中读取而已。那么spring是怎么实现二者貌似矛盾的逻辑的?很简单,在ApplicationContext容器内置一个原生的BeanFactory,在初始化的过程中,系统代码主动调用原生的BeanFactory一次getBean()就行了,此时完成依赖注入,而我们业务代码首次调用的时候,其实已经是第二次调用了,finishBeanFactoryInitialization()正是该策略的系统代码。

《BeanFactory和ApplicationContext的区别》有二者加载bean实例时机的介绍

1. finishBeanFactoryInitialization()

首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:finishBeanFactoryInitialization(beanFactory),单击该行代码跳转到具体的实现。

该方法内的getBean()正是帮我我们提前实例化单例且非lazy原理的核心!这样业务中的首次调用其实已经是第二次调用了!

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    
    
     // 1.初始化此上下文的转换服务
    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));
    }
   
    // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
    if (!beanFactory.hasEmbeddedValueResolver()) {
    
    
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
    
    
            @Override
            public String resolveStringValue(String strVal) {
    
    
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    // 3.初始化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);
     
    // 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
    beanFactory.freezeConfiguration();
 
    // [5].实例化所有剩余(非懒加载)单例对象
    beanFactory.preInstantiateSingletons();
}

[4] 冻结所有bean定义,保证线程安全
重点是 [5].实例化所有剩余(非懒加载)单例对象,见代码块1详解。

1.1 代码块1:[5]preInstantiateSingletons()

preInstantiateSingletons()方法实例化所有剩余(非懒加载)单例对象:

该方法定义在ConfigurableListableBeanFactory接口中,全局就一个实现类DefaultListableBeanFactory

在这里插入图片描述
代码如下,其中[6] getBean(beanName);方法是核心的代码,负责bean的实例化具体

@Override
public void preInstantiateSingletons() throws BeansException {
    
    
   
   
    // 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
 
    // Trigger initialization of all non-lazy singleton beans...
    // 2.遍历beanNames,触发所有非懒加载单例bean的初始化
    for (String beanName : beanNames) {
    
    
        // 3.获取beanName对应的MergedBeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 4.过滤bd,只有符合条件的才会试图出去创建bean实例:不是抽象类 && 是单例 && 不是懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    
    
            // 5.判断beanName对应的bean是否为FactoryBean
            if (isFactoryBean(beanName)) {
    
    
                // 5.1 通过beanName获取FactoryBean实例
                // 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                // 5.2 判断这个FactoryBean是否希望急切的初始化
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    
    
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
    
    
                        @Override
                        public Boolean run() {
    
    
                            return ((SmartFactoryBean<?>) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                } else {
    
    
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
    
    
                    // 5.3 如果希望急切的初始化,则通过beanName获取bean实例
                    getBean(beanName);
                }
            } else {
    
    
                // [6].如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
                getBean(beanName);
            }
        }
    }
 
    // Trigger post-initialization callback for all applicable beans...
    // 7.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
    for (String beanName : beanNames) {
    
    
        // 7.1 拿到beanName对应的bean实例
        Object singletonInstance = getSingleton(beanName);
        // 7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
        if (singletonInstance instanceof SmartInitializingSingleton) {
    
    
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            // 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
            if (System.getSecurityManager() != null) {
    
    
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
    
    
                    @Override
                    public Object run() {
    
    
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            } else {
    
    
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

3.获取 beanName 对应的 MergedBeanDefinition,见代码块2详解。
4.过滤bd,只有符合条件的才会试图出去创建bean实例:不是抽象类 && 是单例 && 不是懒加载,比如如果是需要懒加载的,就要避免加载。
5.判断 beanName 对应的 bean 是否为 FactoryBean,见代码块6详解。好在不管结果如何,最终都会通过5.3或6调用getBean方法

为什么要区分 FactoryBean?因为getBean(“apple”) 、getBean("&apple")是实例化2个不同的bean,下文有详细解释。

5.3 和 6. 通过 beanName 获取 bean 实例,其实也就是实例化bean,finishBeanFactoryInitialization() 方法的核心,限于篇幅,在下一篇文章开始介绍。

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

1.1.1 代码块2:getMergedLocalBeanDefinition()

获取beanName对应的MergedBeanDefinition

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    
    
    
    // 1.检查beanName对应的MergedBeanDefinition是否存在于缓存中
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null) {
    
    
        // 2.如果存在于缓存中则直接返回
        return mbd;
    }
    // 3.如果不存在于缓存中
    // 3.1 getBeanDefinition(beanName): 获取beanName对应的BeanDefinition,从beanDefinitionMap缓存中获取
    // 3.2 getMergedBeanDefinition: 根据beanName和对应的BeanDefinition,获取MergedBeanDefinition
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

3.2 根据 beanName 和 beanName 对应的 BeanDefinition,获取 MergedBeanDefinition,主要调用getMergedBeanDefinition()方法,见代码块3详解。

1.1.1.1 代码块3:getMergedBeanDefinition()

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
        throws BeanDefinitionStoreException {
    
    
 
    return getMergedBeanDefinition(beanName, bd, null);
}
 
protected RootBeanDefinition getMergedBeanDefinition(
        String beanName, BeanDefinition bd, BeanDefinition containingBd)
        throws BeanDefinitionStoreException {
    
    
    // 1.加锁再进行操作
    synchronized (this.mergedBeanDefinitions) {
    
    
        // 用于存储bd的MergedBeanDefinition,也就是该方法的结果
        RootBeanDefinition mbd = null;
 
        // Check with full lock now in order to enforce the same merged instance.
        if (containingBd == null) {
    
    
            // 2.检查beanName对应的MergedBeanDefinition是否存在于缓存中
            mbd = this.mergedBeanDefinitions.get(beanName);
        }
 
        // 3.如果beanName对应的MergedBeanDefinition不存在于缓存中
        if (mbd == null) {
    
    
            if (bd.getParentName() == null) {
    
    
                // 4.如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作,
                // 也就是bd的MergedBeanDefinition就是bd本身(可能需要转成RootBeanDefinition)
              
                if (bd instanceof RootBeanDefinition) {
    
    
                    // 4.1 如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本
                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                } else {
    
    
                    // 4.2 否则,将bd作为参数,构建一个新的RootBeanDefinition。
                    // 正常使用下,BeanDefinition在被加载后是GenericBeanDefinition或ScannedGenericBeanDefinition
                    mbd = new RootBeanDefinition(bd);
                }
            } else {
    
    
                // 5.否则,bd存在父定义,需要与父定义合并
                // Child bean definition: needs to be merged with parent.
                BeanDefinition pbd;
                try {
    
    
                    // 5.1 获取父定义的beanName
                    String parentBeanName = transformedBeanName(bd.getParentName());
                    // 5.2 如果父定义的beanName与该bean的beanName不同
                    if (!beanName.equals(parentBeanName)) {
    
    
                        // 5.3 获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,也就是bd的爷爷定义...)
                        pbd = getMergedBeanDefinition(parentBeanName);
                    } else {
    
    
                        // 5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
                        // 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
                        BeanFactory parent = getParentBeanFactory();
                        if (parent instanceof ConfigurableBeanFactory) {
    
    
                            // 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                        } else {
    
    
                            // 5.6 如果父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.
                // 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
                mbd = new RootBeanDefinition(pbd);
                // 5.8 使用bd覆盖父定义
                mbd.overrideFrom(bd);
            }
 
            // Set default singleton scope, if not configured before.
            // 6.如果没有配置scope,则设置成默认的singleton
            if (!StringUtils.hasLength(mbd.getScope())) {
    
    
                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.
            // 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton,则将mdb的scope设置为containingBd的scope
            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
    
    
                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)
            // 8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
            if (containingBd == null && isCacheBeanMetadata()) {
    
    
                this.mergedBeanDefinitions.put(beanName, mbd);
            }
        }
 
        // 9.返回MergedBeanDefinition
        return mbd;
    }
}

3 再次判断缓存中是否已经存在对应的MergedBeanDefinition,如果存在直接返回,不存在,则要去创建一个。创建的时候,又细分为是否存在父定义,没有父定义,走分支4,存在父定义,走分支5

4.没有父定义,走该分支
5.有父定义,走该分支

  • 5.1 获取父定义的 beanName,这边有一个 beanName 的转换操作,之后会经常用到,见代码块4详解。
  • 5.3 获取父定义的 MergedBeanDefinition,见代码块5详解。
  • 5.7 和 5.8 就是合并操作,也就是我们之前一直说的 MergedBeanDefinition 的由来。

8.将该 beanName 与 MergedBeanDefinition 放到 mergedBeanDefinitions 缓存,后续再走到代码块2时,就会直接返回缓存里的数据。

1.1.1.1.1 代码块4:transformedBeanName

获取父定义的 beanName,将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。

protected String transformedBeanName(String name) {
    
    
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
 
public static String transformedBeanName(String name) {
    
    
    Assert.notNull(name, "'name' must not be null");
    String beanName = name;
    // 如果beanName带有 "&" 前缀,则去掉
    while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
    
    
        beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
    }
    return beanName;
}
 
public String canonicalName(String name) {
    
    
    String canonicalName = name;
    // Handle aliasing...
    String resolvedName;
    do {
    
    
        // 将别名解析成真正的beanName
        resolvedName = this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
    
    
            canonicalName = resolvedName;
        }
    }
    while (resolvedName != null);
    return canonicalName;
}

这边简单的介绍下 FactoryBean。

1.1.1.1.1.1 FactoryBean

一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。而 FactoryBean 是一种特殊的 bean,它是个工厂 bean,可以自己创建 bean 实例,如果一个类实现了 FactoryBean 接口,则该类可以自己定义创建实例对象的方法,只需要实现它的 getObject() 方法。

注:很多中间件都利用 FactoryBean 来进行扩展。

例如以下例子:

public class AppleFactoryBean implements FactoryBean<Apple> {
    
    
   //实现 `getObject()` 方法
    @Override
    public Apple getObject() throws Exception {
    
    
        Apple apple = new Apple();
        apple.setName("bigApple");
        return apple;
    }
 
    @Override
    public Class<?> getObjectType() {
    
    
        return Apple.class;
    }
 
    @Override
    public boolean isSingleton() {
    
    
        return true;
    }
}

为了区分 “FactoryBean” 和 “FactoryBean 创建的 bean 实例”,Spring 使用了 “&” 前缀。假设我们的 beanName 为 apple,则 getBean(“apple”) 获得的是 AppleFactoryBean 通过 getObject() 方法创建的 bean 实例;而 getBean("&apple") 获得的是 AppleFactoryBean 本身。

1.1.1.1.2 代码块5:getMergedBeanDefinition

获取父定义的MergedBeanDefinition

@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
    
    
    // 1.获取真正的beanName(解析别名)
    String beanName = transformedBeanName(name);
 
    // Efficiently check whether bean definition exists in this factory.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
    
    
        // 2.如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
        // 则调用父BeanFactory去获取beanName的MergedBeanDefinition
        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
    }
    // Resolve merged bean definition locally.
    // 3.在当前BeanFactory中解析beanName的MergedBeanDefinition
    return getMergedLocalBeanDefinition(beanName);
}

这边引入了一个 “父 BeanFactory” 的概念,稍微解释下。

1.1.1.1.2.1 父 BeanFactory

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

1.1.2 代码块6:isFactoryBean

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    
    
    // 1.拿到真正的beanName(去掉&前缀、解析别名)
    String beanName = transformedBeanName(name);
 
    // 2.尝试从缓存获取Bean实例对象
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null) {
    
    
        // 3.beanInstance存在,则直接判断类型是否为FactoryBean
        return (beanInstance instanceof FactoryBean);
    } else if (containsSingleton(beanName)) {
    
    
        // 4.如果beanInstance为null,并且beanName在单例对象缓存中,则代表beanName对应的单例对象为空对象,返回false
        // null instance registered
        return false;
    }
 
    // No singleton instance found -> check bean definition.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
    
    
        // 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean
        // No bean definition found in this factory -> delegate to parent.
        return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
    }
    // 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
    return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

2.尝试从缓存获取 bean 实例对象,见代码块7详解。

6.通过 MergedBeanDefinition 来检查 beanName 对应的 bean 是否为 FactoryBean。首先通过 getMergedLocalBeanDefinition 方法获取 beanName 的 MergedBeanDefinition,该方法在代码块2已经解析过;接着调用 isFactoryBean 来检查 beanName 对应的 bean 是否为 FactoryBean,见代码块8详解。

1.1.2.1 代码块7:getSingleton

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    
    
    // 1.从单例对象缓存中获取beanName对应的单例对象
    Object singletonObject = this.singletonObjects.get(beanName);
    // 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    
    
        // 3.加锁进行操作
        synchronized (this.singletonObjects) {
    
    
            // 4.从早期单例对象缓存中获取单例对象(之所称成为早期单例对象,是因为earlySingletonObjects里
            // 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 5.如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用
            if (singletonObject == null && allowEarlyReference) {
    
    
                // 6.从单例工厂缓存中获取beanName的单例工厂
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
    
    
                    // 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
                    singletonObject = singletonFactory.getObject();
                    // 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
                    // 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 10.返回单例对象
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
 
public boolean isSingletonCurrentlyInCreation(String beanName) {
    
    
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

这段代码很重要,在正常情况下,该代码很普通,只是正常的检查下我们要拿的 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 在这边构成了一个类似于 “三级缓存” 的概念。

1.1.2.2 代码块8 isFactoryBean

protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    
    
    // 1.拿到beanName对应的Bean实例的类型
    Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
    // 2.返回beanType是否为FactoryBean本身、子类或子接口
    return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}

1.拿到 beanName 对应的 bean 实例的类型,见代码块9详解。

1.1.2.2.1 代码块9:predictBeanType
@Override
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    
    
    // 1.拿到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;
                // 3.调用predictBeanType方法
                Class<?> predicted = ibp.predictBeanType(targetType, beanName);
                if (predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] ||
                        FactoryBean.class.isAssignableFrom(predicted))) {
    
    
                    // 4.如果predicted不为空 && (typesToMatch长度不为1 || typesToMatch[0]不为FactoryBean.class ||
                    // predicted是FactoryBean本身、子类或子接口),则返回predicted
                    return predicted;
                }
            }
        }
    }
    // 5.否则返回beanName的类型
    return targetType;
}

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

总结

本文执行了创建 bean 实例前的一些准备操作。主要是引入了 FactoryBean 这一特殊的 bean,获取 BeanDefinition 的 MergedBeanDefinition,最后将 BeanDefinition 统一转换成 RootBeanDefinition。

参考:
《》

猜你喜欢

转载自blog.csdn.net/m0_45406092/article/details/114983754
今日推荐