SpringBoot

AbstractBeanFactory#getBean()核心流

2022-12-06  本文已影响0人  王侦

1.重载的getBean()方法

    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name, null, args, false);
    }

    /**
     * Return an instance, which may be shared or independent, of the specified bean.
     * @param name the name of the bean to retrieve
     * @param requiredType the required type of the bean to retrieve
     * @param args arguments to use when creating a bean instance using explicit arguments
     * (only applied when creating a new instance as opposed to retrieving an existing one)
     * @return an instance of the bean
     * @throws BeansException if the bean could not be created
     */
    public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
            throws BeansException {

        return doGetBean(name, requiredType, args, false);
    }

2.AbstractBeanFactory#doGetBean

核心流程:

    protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {

        // name可能是别名(要获取到真是的beanName),也可能是&开头的(FactoryBean)
        String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        // 到缓存中获取共享单实例,单参数getSingleton
        Object sharedInstance = getSingleton(beanName);

        //CASE1:缓存中有对应的数据,此时缓存数据可能是普通单实例 也可能是 FactoryBean,所以需要根据name来进行判断,并且返回数据。
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //这里为什么又要套呢?为啥不直接拿回去用呢?
            //其实,你从IOC中拿到的对象,它可能是普通单实例,也可能是FactoryBean实例。
            //如果是FactoryBean实例,这个时候还要进行处理。主要是看name是带“&” 还是 不带“&”,
            //带“&”说明这次getBean想要拿FactoryBean对象。
            //否则是要拿FactoryBean内部管理的实例。
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        //CASE2:缓存中没有我们的数据,我们应该自己创建了
        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            //1、原型循环依赖问题判定
            //举个例子:
            //prototypeA -> B, B -> prototypeA
            //1.会向正在创建中的原型集合内添加一个字符串 “A”   下面beforePrototypeCreation(beanName);
            //2.创建prototypeA对象,只是一个早期对象。
            //3.处理prototypeA的依赖,发现A依赖了B类型的对象
            //4.触发了Spring.getBean(“B”)的操作。
            //5.根据B的构造方法反射创建出来了B的早期实例
            //6.Spring处理B对象的依赖,发现依赖了A。
            //7.Spring转头回来再次去获取A去了。getBean(“A”).
            //8.条件会返回true,最终抛出异常,算是结束了循环依赖注入。
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // 父子容器
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                //2.获取合并BD信息
                //为什么需要合并呀?因为BD支持继承
                // 深度拷贝父bd信息,然后子bd覆盖父bd相同信息
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //判断当前BD是否为抽象BD,抽象BD不能创建实例,只能作为父BD让子BD去继承。
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                //3.depends-on属性处理..
                //<bean name="A" depends-on="B" ... />
                //<bean name="B" .../>
                //循环依赖问题
                //<bean name="A" depends-on="B" ... />
                //<bean name="B" depends-on="A" .../>
                //Spring是处理不了这种情况的,需要报错..
                //Spring需要发现这种情况的产生。
                //怎么发现呢? 依靠两个Map,一个map是 dependentBeanMap 另一个是 dependenciesForBeanMap
                //1. dependentBeanMap 记录依赖当前beanName的其他beanName
                //2. dependenciesForBeanMap 记录当前beanName依赖的其它beanName集合
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        //判断循环依赖..
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        //假设<bean name="A" depends-on="B" ... />
                        //dep:B,beanName:A
                        //以B为视角 dependentBeanMap {"B":{"A"}}
                        //以A为视角 dependenciesForBeanMap {"A" :{"B"}}
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                // 单例
                if (mbd.isSingleton()) {
                    //第二个getSingleton方法,这个方法更倾向于创建实例并返回。
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });

                    //这里为啥不直接返回,还调用getObjectForBeanInstance(...)?

                    //这里为什么又要套呢?为啥不直接拿回去用呢?
                    //其实,你从IOC中拿到的对象,它可能是普通单实例,也可能是FactoryBean实例。
                    //如果是FactoryBean实例,这个时候还要进行处理。主要是看name是带“&” 还是 不带“&”,
                    //带“&”说明这次getBean想要拿FactoryBean对象。
                    //否则是要拿FactoryBean内部管理的实例。
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                // 原型
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {
                        //记录当前线程相关的正在创建的原型对象beanName
                        beforePrototypeCreation(beanName);
                        //创建对象
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        //从正在创建中的集合中 移除。
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    String scopeName = mbd.getScope();
                    if (!StringUtils.hasLength(scopeName)) {
                        throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                    }
                    Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

3.从三级缓存中获取实例的getSingleton()

问题:这里为什么搞的两重判断?但是5.3之后又简化了?原因是啥?

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // Quick check for existing instance without full singleton lock
        // 到一级缓存获取
        Object singletonObject = this.singletonObjects.get(beanName);
        // 条件一:一级缓存不存在
        //   1)单实例未创建
        //   2)单实例循环依赖(三级缓存解决setter循环依赖)

        //1.假设Spring先实例化A,首先拿到A的构造方法,进行反射创建出来A的早期实例对象,这个时候,这个早期对象被包装成了ObjectFactory对象,放到了3级缓存。
        //2.处理A的依赖数据,检查发现,A它依赖了B对象,所以接下来,Spring就会去根据B类型到容器中去getBean(B.class),这里就递归了。
        //3.拿到B的构造方法,进行反射创建出来B的早期实例对象,它也会把B包装成ObjectFactory对象,放到3级缓存。
        //4.处理B的依赖数据,检查发现,B它依赖了A对象,所以接下来,Spring就会去根据A类型到容器中去getBean(A.class),去拿A对象,这个又递归了。
        //5.程序还会走到当前这个方法。getSingleton这个方法。
        //6.条件一成立,条件二也会成立。
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            // 检查二级缓存
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 二级缓存没有
            if (singletonObject == null && allowEarlyReference) {
                synchronized (this.singletonObjects) {
                    // Consistent creation of early reference within full singleton lock
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        singletonObject = this.earlySingletonObjects.get(beanName);
                        if (singletonObject == null) {
                            //Spring为什么需要有3级缓存存在,而不是只有2级缓存呢?
                            //AOP,靠什么实现的呢?动态代理
                            //静态代理:需要手动写代码,实现一个新的java文件,这个java类 和 需要代理的对象 实现同一个接口,内部维护一个被代理对象(原生)
                            //代理类,在调用原生对象前后,可以加一些逻辑. 代理对象 和 被代理对象 是两个不同的对象,内存地址一定是不一样的。
                            //动态代理:不需要人为写代码了,而是依靠字节码框架动态生成class字节码文件,然后jvm再加载,然后也一样 也是去new代理对象,这个
                            //代理对象 没啥特殊的,也是内部保留了 原生对象,然后在调用原生对象前后 实现的 字节码增强。
                            //3级缓存在这里有什么目的呢?
                            //3级缓存里面保存的是对象工厂,这个对象工厂内部保留着最原生的对象引用,ObjectFactory的实现类,getObject()方法,它需要考虑一个问题。
                            //它到底要返回原生的,还是增强后的。
                            //getObject会判断当前这个早期实例 是否需要被增强,如果是,那么提前完成动态代理增强,返回代理对象。否则,返回原生对象。
                            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                            if (singletonFactory != null) {
                                // 将三级缓存数据提升到二级
                                singletonObject = singletonFactory.getObject();
                                this.earlySingletonObjects.put(beanName, singletonObject);
                                this.singletonFactories.remove(beanName);
                            }
                        }
                    }
                }
            }
        }
        return singletonObject;
    }

4.getObjectForBeanInstance获取不同情况下的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.
        // 想拿FactoryBean本身对象
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            }
            if (mbd != null) {
                mbd.isFactoryBean = true;
            }
            return beanInstance;
        }

        //执行到这里,有几种情况呢?
        //1.当前bean实例就是普通单实例
        //2.当前bean实例是FactoryBean接口实现类,但是本次请求要拿的是FactoryBean实现类内部管理的实例。

        // Now we have the bean instance, which may be a normal bean or a FactoryBean.
        // If it's a FactoryBean, we use it to create a bean instance, unless the
        // caller actually wants a reference to the factory.
        //1.当前bean实例就是普通单实例
        if (!(beanInstance instanceof FactoryBean)) {
            return beanInstance;
        }

        Object object = null;
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        else {
            // 先从缓存拿
            object = getCachedObjectForFactoryBean(beanName);
        }
        // 缓存没有,FactoryBean.getObject()获取
        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)) {
                //拿到合并后的BD信息。
                //为什么是合并后的呢?因为咱们的BD是直接继承的。合并后的BD信息是包含继承回来的BD。
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            //synthetic 默认值是false 表示这是一个用户对象,如果是true 表示是系统对象。
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }
    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        //CASE1:FactoryBean内部维护的对象是单实例
        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) {
                        object = alreadyThere;
                    }
                    else {
                        // 一般情况是都是true,是普通bean,不是系统生成的bean
                        if (shouldPostProcess) {
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            beforeSingletonCreation(beanName);
                            try {
                                // applyBeanPostProcessorsAfterInitialization,会调用一下后置处理器,但不是经过完整生命周期的
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                            finally {
                                afterSingletonCreation(beanName);
                            }
                        }
                        if (containsSingleton(beanName)) {
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        //CASE2:FactoryBean内部维护的对象非单实例
        else {
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }

特别注意,对于FactoryBean#getObject()会调用BeanPostProcessor#postProcessAfterInitialization(),这些对象是没有经过Bean完整的生命周期的,只是在这里调用了一下初始化后的方法。

5.depends-on的循环依赖处理

    protected boolean isDependent(String beanName, String dependentBeanName) {
        synchronized (this.dependentBeanMap) {
            return isDependent(beanName, dependentBeanName, null);
        }
    }

    //<bean name="A" depends-on="B" ...>
    //<bean name="B" depends-on="A" ...>

    // step1.先处理了<bean name="A" depends-on="B" ...>
    //  以B为视角 dependentBeanMap {"B":{"A"}}
    //  以A为视角 dependenciesForBeanMap {"A" :{"B"}}
    // step2.发现依赖B,此时getBean("B"),<bean name="B" depends-on="A" ...>,发现B依赖A
    //   beanName:B,  dependentBeanName:A
    private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
        if (alreadySeen != null && alreadySeen.contains(beanName)) {
            return false;
        }
        String canonicalName = canonicalName(beanName);
        //1. dependentBeanMap 记录依赖当前beanName的其他beanName
        //2. dependenciesForBeanMap 记录当前beanName依赖的其它beanName集合
        //获取依赖B的bean:{"A"}
        Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
        if (dependentBeans == null) {
            return false;
        }
        //{"A"} 包含A,所以条件会成立,这里返回true,表示产生了循环依赖..
        // dependentBeanName A 表示
        //     beanName B 依赖dependentBeanName A
        // dependentBeans表示
        //     dependentBeans 依赖 表示beanName B
        // 如果dependentBeans包含dependentBeanName A,就形成了循环依赖
        if (dependentBeans.contains(dependentBeanName)) {
            return true;
        }
        //<bean name="A" dp="B">
        //<bean name="B" dp="C">
        //<bean name="C" dp="A">

        // 现在已处理前面两个,走到第三个
        //dependentBeanMap={B:{A}, C:{B}}
        //isDependent(C,A)
        //C#dependentBeans = {B}
        //isDependent(B, A);
        //B#dependentBeans = {A}
        //就判断出来当前发生循环依赖问题了...返回true了。
        for (String transitiveDependency : dependentBeans) {
            if (alreadySeen == null) {
                alreadySeen = new HashSet<>();
            }
            alreadySeen.add(beanName);
            if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
                return true;
            }
        }
        return false;
    }

6.创建实例的getSingleton

                    //第二个getSingleton方法,这个方法更倾向于创建实例并返回。
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //容器销毁时,会设置这个属性为true,这个时候就不能再创建bean实例了,直接抛错。
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                }
                //将当前beanName放入到“正在创建中单实例集合”,放入成功,说明没有产生循环依赖,失败,则产生循环依赖,里面会抛异常。
                //举个例子:构造方法参数依赖
                //A->B    B->A
                //1.加载A,根据A的构造方法,想要去实例化A对象,但是发现A的构造方法有一个参数是B(在这之前,已经向这个集合中添加了 {A})
                //2.因为A的构造方法依赖B,所以触发了加载B的逻辑..
                //3.加载B,根据B的构造方法,想要去实例化B对象,但是发现B的构造方法有一个参数是A(在这之前,已经向这个集合中添加了 {A,B})
                //4.因为B的构造方法依赖A,所以再次触发了加载A的逻辑..
                //5.再次来到这个getSingleton方法里,调用beforeSingletonCreation(A),因为创建中集合 已经有A了,所以添加失败,抛出异常
                //完事。
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    // 调用外面传进来的lambda表达式:createBean(beanName, mbd, args);
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) {
                    // Has the singleton object implicitly appeared in the meantime ->
                    // if yes, proceed with it since the exception indicates that state.
                    singletonObject = this.singletonObjects.get(beanName);
                    if (singletonObject == null) {
                        throw ex;
                    }
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {
                    addSingleton(beanName, singletonObject);
                }
            }
            return singletonObject;
        }
    }
上一篇下一篇

猜你喜欢

热点阅读