Spring IOC:finishBeanFactoryInitialization调用链

参考资料:

《Spring IoC源码学习:finishBeanFactoryInitialization 详解》

写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。

 

目录

一、概述

        1、finishBeanFactoryInitialization

        2、核心概念

        (1)、MergedBeanDefinition

        (2)、FactoryBean

        3、finishBeanFactoryInitialization

二、preInstantiateSingletons

        1、preInstantiateSingletons

        2、getMergedLocalBeanDefinition

        3、getMergedBeanDefinition

        4、transformedBeanName

        5、getMergedBeanDefinition

三、isFactoryBean

        1、isFactoryBean

        2、getSingleton

        3、isFactoryBean

总结:


一、概述

        1、finishBeanFactoryInitialization

        在IOC核心方法AbstractApplicationContext#refresh()中,经过obtainFreshBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors三个前置步骤后,就到了finishBeanFactoryInitialization。finishBeanFactoryInitialization是这四个方法中最复杂也是最重要的,是整个 Spring IoC 核心中的核心,负责将所有剩余的非懒加载单例 bean实例化。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

        2、核心概念

        (1)、MergedBeanDefinition

        在后续流程中我们会接触到getMergedBeanDefinition等方法,个人理解为合并beanDefinition对于一个 bean 定义来说,可能存在以下几种情况:

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

        后面两点,主要是因为通常 BeanDefinition 在之前加载到 BeanFactory 中的时候,通常是被封装成 GenericBeanDefinition (当使用xml配置来注册 bean,则该 bean 定义会被封装成GenericBeanDefinition)或 ScannedGenericBeanDefinition(使用<context:component-scan /> + @Compoment时),但是从这边之后 bean 的后续流程处理都是针对 RootBeanDefinition,因此在这边会统一将 BeanDefinition 转换成 RootBeanDefinition。


        (2)、FactoryBean

        注意和BeanFactory的区别,FactoryBean是利用工厂模式,为所需类提供单实例对象的方法,Spring中,继承了FactoryBean<?>接口的都是工厂Bean,用来为别的类提供单例对象。需要注意的是,FactoryBean在IOC中的beanName会自带“&”前缀,假设我们有Apple类和AppleFactoryBean工厂类,那么getBean("&apple") 获得的是 AppleFactoryBean,而getBean("apple") 获得的则是AppleFactoryBean通过getObject()方法创建的Apple实例
 

        3、finishBeanFactoryInitialization

        (1)完成实例化前的准备工作,初始化上下文转换服务器、注册解析器等

        (2)冻结bean,防止创建bean实例时被修改,通过限定beanDefinitionNames的方式实现

        (3)实例化所有剩余非懒加载的单实例bean

// AbstractApplicationContext.java
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化此上下文的转换服务
    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));
    }
 
    // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
 
    // 初始化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);
 
    // 冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
    beanFactory.freezeConfiguration();
 
    // 实例化所有剩余(非懒加载)单例对象
    beanFactory.preInstantiateSingletons();
}

二、preInstantiateSingletons

        1、preInstantiateSingletons

        (1)创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义,然后遍历beanNames,触发所有非懒加载单例bean的初始化。获取beanName对应的MergedBeanDefinition,将有需要的BeanDefinition进行合并。

       (2)过滤出所有非懒加载单例的bean,并判断beanName对应的bean是否为FactoryBean,如不是,则正常通过getBean(beanName)进行实例化,反之,则先通过getBean(beanName)拿到的是FactoryBean的Bean实例,再通过isEagerInit判断是否需要立即初始化,通过的话则依然是调用getBean(beanName)来实例化。

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

// DefaultListableBeanFactory.java
@Override
public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Pre-instantiating singletons in " + this);
    }
 
    // 创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
 
    // 遍历beanNames,触发所有非懒加载单例bean的初始化
    for (String beanName : beanNames) {
        // 获取beanName对应的MergedBeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 判断beanName对应的bean是否为FactoryBean
            if (isFactoryBean(beanName)) {
                // 通过beanName获取FactoryBean实例
                // 通过getBean(&beanName)拿到的是FactoryBean本身;通过getBean(beanName)拿到的是FactoryBean创建的Bean实例
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                // 判断这个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) {
                    // 如果希望急切的初始化,则通过beanName获取bean实例
                    getBean(beanName);
                }
            } else {
                // 如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
                getBean(beanName);
            }
        }
    }
 
    // 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
    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(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

 

        2、getMergedLocalBeanDefinition

        (1)判断MergedBeanDefinition是否已在缓存中,如存在则直接返回

        (2)通过beanName获取对应的BeanDefinition,再调用getMergedBeanDefinition获取MergedBeanDefinition并加入缓存中

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

        3、getMergedBeanDefinition

        (1)校验beanName对应的MergedBeanDefinition不存在于缓存中。

        (2)如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作,也就是bd的MergedBeanDefinition就是bd本身(可能需要转成RootBeanDefinition)。

        (2.1)如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本。

        (2.2)否则,将bd作为参数构建一个RootBeanDefinition(bd一般为GenericBeanDefinition或ScannedGenericBeanDefinition)。

        (3)bd存在父定义,需要与父定义合并,首先获取父定义的beanName。

        (3.1)如果父定义的beanName与该bean的beanName不同,获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,这里实际上是向上递归到最顶层)。

        (3.2)如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory。

        (3.2.1)如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition。

        (3.2.2)如果父BeanFactory不是ConfigurableBeanFactory,则抛异常。

        (3.3)使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝),并使用bd覆盖父定义

        (4)设置scope,并将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用。

// AbstractBeanFactory.java
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 {
    // 加锁再进行操作
    synchronized (this.mergedBeanDefinitions) {
        // 用于存储bd的MergedBeanDefinition,也就是该方法的结果
        RootBeanDefinition mbd = null;
 
        if (containingBd == null) {
            // 检查beanName对应的MergedBeanDefinition是否存在于缓存中
            mbd = this.mergedBeanDefinitions.get(beanName);
        }
 
        // 如果beanName对应的MergedBeanDefinition不存在于缓存中
        if (mbd == null) {
            if (bd.getParentName() == null) {
                // 如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作,
                // 也就是bd的MergedBeanDefinition就是bd本身(可能需要转成RootBeanDefinition)
                if (bd instanceof RootBeanDefinition) {
                    // 如果bd的类型为RootBeanDefinition,则bd的MergedBeanDefinition就是bd本身,则直接克隆一个副本
                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                } else {
                    // 否则,将bd作为参数,构建一个RootBeanDefinition。
                    // 正常使用下,BeanDefinition在被加载后是GenericBeanDefinition或ScannedGenericBeanDefinition
                    mbd = new RootBeanDefinition(bd);
                }
            } else {
                // 否则,bd存在父定义,需要与父定义合并
                BeanDefinition pbd;
                try {
                    // 获取父定义的beanName
                    String parentBeanName = transformedBeanName(bd.getParentName());
                    // 如果父定义的beanName与该bean的beanName不同
                    if (!beanName.equals(parentBeanName)) {
                        // 获取父定义的MergedBeanDefinition(因为父定义也可能有父定义,也就是bd的爷爷定义...)
                        pbd = getMergedBeanDefinition(parentBeanName);
                    } else {
                        // 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
                        // 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
                        BeanFactory parent = getParentBeanFactory();
                        if (parent instanceof ConfigurableBeanFactory) {
                            // 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                            pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                        } else {
                            // 如果父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);
                }
                // 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
                mbd = new RootBeanDefinition(pbd);
                // 使用bd覆盖父定义
                mbd.overrideFrom(bd);
            }
 
            // 如果没有配置scope,则设置成默认的singleton
            if (!StringUtils.hasLength(mbd.getScope())) {
                mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
            }
 
            // 如果containingBd不为空 && containingBd不为singleton && mbd为singleton,则将mdb的scope设置为containingBd的scope
            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                mbd.setScope(containingBd.getScope());
            }
 
            // 将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
            if (containingBd == null && isCacheBeanMetadata()) {
                this.mergedBeanDefinitions.put(beanName, mbd);
            }
        }
 
        // 返回MergedBeanDefinition
        return mbd;
    }
}

        4、transformedBeanName

        将 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;
}

        5、getMergedBeanDefinition

        依然是根据beanName去获取BeanFactory中的MergedBeanDefinition,getMergedLocalBeanDefinition在上文中已经解释过,这里略过。

@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
    // 获取真正的beanName(解析别名)
    String beanName = transformedBeanName(name);
 
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        // 如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
        // 则调用父BeanFactory去获取beanName的MergedBeanDefinition
        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
    }
    // 在当前BeanFactory中解析beanName的MergedBeanDefinition
    return getMergedLocalBeanDefinition(beanName);
}

三、isFactoryBean

        1、isFactoryBean

        (1)拿到真正的beanName(去掉&前缀、解析别名),并尝试从缓存获取Bean实例对象。

        (2)beanInstance存在,则直接判断类型是否为FactoryBean,如果不存在,并且beanName在单例对象缓存中,则代表beanName对应的单例对象为空对象,返回false。

        (3)如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory,则调用父BeanFactory判断是否为FactoryBean。

        (4)通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean。

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

 

        2、getSingleton

        (1)从单例对象缓存中获取beanName对应的单例对象,如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中,则加锁并并行操作。

        (2)从早期单例对象缓存中获取单例对象(早期单例对象,是指earlySingletonObjects里的对象,都是通过singletonFactory创建出来的,还未进行属性填充等操作),判断早期单例对象缓存中是否没有,并且允许创建早期单例对象引用,则从单例工厂缓存(singletonFactories)中获取beanName的单例工厂(singletonFactory)。

        (3)如果存在单例对象工厂,则通过工厂创建一个单例对象(singletonObject )。将该对象放到早期单例对象缓存中,并移除该beanName对应的单例对象工厂。(因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了, 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂)。

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 从单例对象缓存中获取beanName对应的单例对象
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
    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缓存了,
                    // 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 返回单例对象
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
 
public boolean isSingletonCurrentlyInCreation(String beanName) {
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

4个重要缓存:

  • singletonObjects缓存:存放beanName ->bean实例的映射。
  • earlySingletonObjects缓存:存放beanName -> bean对象的映射(注意,这里存放的是早期单例 bean 对象,还未进行属性填充、初始化)
  • singletonFactories缓存:存放beanName ->单例工厂缓存的映射。
  • singletonsCurrentlyInCreation缓存:当前正在创建单例 bean 对象的 beanName 集合。

       

        3、isFactoryBean

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

总结:

      本文中主要了解了对于不同的bean的处理步骤,主要分为普通bean和FactoryBean。

      普通bean直接调用getBean创建,FactoryBean则需要获取BeanDefinition的 MergedBeanDefinition,最后将BeanDefinition统一转换成 RootBeanDefinition。

       bean实例化核心方法getBean会在后续进行整理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值