Spring源码分析(四)Bean生命周期源码分析2:合并BeanDefinition、FactoryBean

Spring容器启动,扫描得到所有BeanDefinition之后,就会先实例化所有非懒加载的单例Bean的

入口

Spring容器启动刷新的方法里:
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
在这里插入图片描述
我们知道beanFacotory就是DefaultListableBeanFactory
在这里插入图片描述
org.springframework.beans.factory.support.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.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        //1. 合并BeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

        //判断BeanDefinition,非抽象,是单例,非懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            //2. FactoryBean逻辑,第二节提到过
            if (isFactoryBean(beanName)) {
                //FACTORY_BEAN_PREFIX="&"
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {...}
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        //创建真正的Bean对象(这里是FactoryBean.getObject()对象)
                        getBean(beanName);
                    }
                }
            }
            else {
                //3. 创建Bean对象
                getBean(beanName);
            }
        }
    }

	// 4. 所有非懒加载单例Bean都创建完成后
    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        // 从单例池里拿beanName对应的单例Bean(里面实现涉及到循环依赖,以后讲,先简单理解)
        Object singletonInstance = getSingleton(beanName);
        // 判断单例Bean是否实现了SmartInitializingSingleton接口
        // 这个接口也属于Spring生命周期里的一种接口
        if (singletonInstance instanceof SmartInitializingSingleton) {
            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                    .tag("beanName", beanName);
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {...}
            else {
                //触发afterSingletonsInstantiated方法
                smartSingleton.afterSingletonsInstantiated();
            }
            smartInitialize.end();
        }
    }
}

1. 合并BeanDefinition

应用场景

通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition,和Java父子类类似,但是完全不是一回事。

BeanDefinition也可以设置成抽象的,这样该BeanDefinition就不会创建Bean实例,可以被其他BeanDefinition继承(不设置抽象也能继承)
在这里插入图片描述
父子BeanDefinition实际用的比较少,使用是这样的,比如:
这么定义的情况下,child是单例Bean:

<bean id="parent" class="com.yth.service.Parent" scope="prototype"/>
<bean id="child" class="com.yth.service.Child"/>

但是这么定义的情况下,child就是原型Bean了:

<bean id="parent" class="com.yth.service.Parent" scope="prototype"/>
<bean id="child" class="com.yth.service.Child" parent="parent"/>

因为child的父BeanDefinition是parent,所以会继承parent上所定义的scope属性。

而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整的child的BeanDefinition。

源码分析

org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    // 合并过,就直接返回
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null && !mbd.stale) {
        return mbd;
    }
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
        throws BeanDefinitionStoreException {

    return getMergedBeanDefinition(beanName, bd, null);
}

mergedBeanDefinitions:合并之后的BeanDefinition Map,value就是RootBeanDefinition
在这里插入图片描述

protected RootBeanDefinition getMergedBeanDefinition(
        String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
        throws BeanDefinitionStoreException {

    synchronized (this.mergedBeanDefinitions) {
        RootBeanDefinition mbd = null;
        RootBeanDefinition previous = null;

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

        if (mbd == null || mbd.stale) {
            previous = mbd;
            // 判断有没有父亲
            if (bd.getParentName() == null) {
                // Use copy of given root bean definition.
                // 没有parent就生成一个新的RootBeanDefinition
                if (bd instanceof RootBeanDefinition) {
                	//复制新的
                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                }
                else {
                	//new新的
                    mbd = new RootBeanDefinition(bd);
                }
            }
            else {
                // Child bean definition: needs to be merged with parent.
                BeanDefinition pbd;
                try {
                    // 获取parentName对应的BeanDefinition
                    String parentBeanName = transformedBeanName(bd.getParentName());
                    if (!beanName.equals(parentBeanName)) {
                        //递归获取父亲的RootBeanDefinition
                        pbd = getMergedBeanDefinition(parentBeanName);
                    }
                    //如果beanName和parentName一样,则从父亲工厂里获取BeanDefinition
                    else {...}
                }
                //最终获取不到会抛异常
                catch (NoSuchBeanDefinitionException ex) {...}
                // Deep copy with overridden values.
                // 深拷贝,生成一个RootBeanDefinition
                // 		先基于父BeanDefinition生成RootBeanDefinition
                mbd = new RootBeanDefinition(pbd);
                //		然后和自己合并,自己优先级更高
                mbd.overrideFrom(bd);
            }

            // Set default singleton scope, if not configured before.
            if (!StringUtils.hasLength(mbd.getScope())) {...}

            // 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()) {...}

            // 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()) {
                //保存到mergedBeanDefinitions Map
                this.mergedBeanDefinitions.put(beanName, mbd);
            }
        }
        if (previous != null) {...}
        return mbd;
    }
}

真正创建Bean的时候,用的是合并之后的这个Map:mergedBeanDefinitions

2. FactoryBean

在这里插入图片描述

2.1 判断是否是FactoryBean

org.springframework.beans.factory.support.AbstractBeanFactory#isFactoryBean(java.lang.String)

这个方法除了这,其他地方也会掉

public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);
    //先从单例池获取FactoryBean本身的对象
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null) {
        return (beanInstance instanceof FactoryBean);
    }
    
    //没有拿到FactoryBean本身的对象,则根据BeanDefinition对象来判断
    //	当前容器没有name对应的BeanDefinition,则从父容器获取
    // No singleton instance found -> check bean definition.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        // No bean definition found in this factory -> delegate to parent.
        return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
    }
    //拿到合并后的BeanDefinition判断是否是FactoryBean
    return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
    //根据BeanDefinition的isFactoryBean属性判断
    Boolean result = mbd.isFactoryBean;
    if (result == null) {
        //isFactoryBean属性缓存为空,则直接根据类的类型判断

        //根据BeanDefinition推测Bean类型(获取BeanDefinition的beanClass属性)
        Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);

        //判断是否实现了FactoryBean接口
        result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
        mbd.isFactoryBean = result;
    }
    return result;
}

BeanDefinition里的很多属性,其实是起到缓存的作用,一开始为null也不影响,会去专门解析,然后在保存起来作为缓存使用。

2.2 创建FactoryBean本身的对象

在这里插入图片描述
在这里插入图片描述
getBean源码见2.4(带一点)、或者3(下一章节讲解)。

2.3 SmartFactoryBean

如果我们FactoryBean实现的是SmartFactoryBean接口:
在这里插入图片描述
并重写了isEagerInit方法,返回true:
在这里插入图片描述
那么Spring容器启动的时候,就会把改FactoryBean对应的getObject()方法的对象生成,否则只有getBean的时候才会生成。
在这里插入图片描述
没有调getBean已经有了:
在这里插入图片描述

2.4 FactoryBean的getObject触发时机

FactoryBean对应的getObject对象是通过调容器getBean方法实例化的

  • beanName获取FactoryBean的getObject对象
  • “&” + beanName获取FactoryBean本身的对象

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {
	//name有可能是 &xxx 或者 xxx
    //如果name是&xxx,beanName返回的beanName就是xxx
    //name如果是别名,beanName就是id
    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {...}
        //如果sharedInstance是FactoryBean,那么就调用getObject()返回对象
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {...}

    return adaptBeanInstance(name, beanInstance, requiredType);
}
//name是&xxx或者xxx
//beanName是xxx
//beanInstance从单例池里拿到的bean
protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // Don't let calling code try to dereference the factory if the bean isn't a factory.
    // 判断name是不是带了&符号,是的话就是FactoryBean的引用
    if (BeanFactoryUtils.isFactoryDereference(name)) {
    	//走到这说明想获取FactoryBean本身
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
    	//判断从单例池里拿到的Bean是不是FactoryBean
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        //是,则直接返回
        return beanInstance;
    }
    
	//走到这说明想获取的是普通Bean对象,或者FacotryBean的getObject对象

    // 单例池里的对象不是FactoryBean,则直接返回
    if (!(beanInstance instanceof FactoryBean)) {
    	//返回普通对象
        return beanInstance;
    }
	
    Object object = null;
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        //先从缓存拿
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        //核心在这里
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    if (factory.isSingleton() && containsSingleton(beanName)) {
        //多线程同时来创建需要控制,保证单例
        synchronized (getSingletonMutex()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
            	//核心在这
                object = doGetObjectFromFactoryBean(factory, beanName);
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {...}
                else {
                    //是否要进行后处理,可以发现FactoryBean只会经过“初始化后”的生命周期
                    if (shouldPostProcess) {...}
                    if (containsSingleton(beanName)) {
                        //放到缓存
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            return object;
        }
    }
    //FactoryBean也支持多例情况
    else {...}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
    Object object;
    try {
        if (System.getSecurityManager() != null) {...}
        else {
            //这里调用了FactoryBean的getObject方法
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {...}
    catch (Throwable ex) {...}

    // Do not accept a null value for a FactoryBean that's not fully
    // initialized yet: Many FactoryBeans just return null then.
    if (object == null) {
        if (isSingletonCurrentlyInCreation(beanName)) {...}
        object = new NullBean();
    }
    return object;
}

3. 创建Bean对象

org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
下一章节讲。

4. SmartInitializingSingleton

应用场景

定义一个单例Bean的时候,可以实现SmartInitializingSingleton接口,它会在所有非懒加载的单例Bean都创建成功以后触发。注意!!是在所有!
在这里插入图片描述

源码分析

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

犬豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值