• bean的创建过程--doGetBean


    protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
            //处理别名,提取对应的beanName
            final String beanName = this.transformedBeanName(name);
            /**
             * 检查缓存中或者实例工厂中是否有对应的实例
             * 为什么会首先使用这段代码呢?
             * 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖
             * Spring创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory
             */
            //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取
            Object sharedInstance = this.getSingleton(beanName);
            Object bean;
            if (sharedInstance != null && args == null) {
                if (this.logger.isDebugEnabled()) {
                    if (this.isSingletonCurrentlyInCreation(beanName)) {
                        this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                    } else {
                        this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                //返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
            } else {
                //只有在单例情况下才会尝试解决循环依赖,如果是原型模式下 则直接抛出如下异常
                if (this.isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
    
                BeanFactory parentBeanFactory = this.getParentBeanFactory();
                //如果beanDefinitionMap中也就是所有已经加载的类中不包括beanname则尝试从parentBeanFactory中检测
                if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                    String nameToLookup = this.originalBeanName(name);
                    //递归到BeanFactory中寻找
                    if (args != null) {
                        return parentBeanFactory.getBean(nameToLookup, args);
                    }
    
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
    
                if (!typeCheckOnly) {
                    this.markBeanAsCreated(beanName);
                }
    
                try {
                    final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                    this.checkMergedBeanDefinition(mbd, beanName, args);
                    String[] dependsOn = mbd.getDependsOn();
                    String[] var11;
                    //若存在依赖则需要递归实例化依赖的bean
                    if (dependsOn != null) {
                        var11 = dependsOn;
                        int var12 = dependsOn.length;
    
                        for(int var13 = 0; var13 < var12; ++var13) {
                            String dependsOnBean = var11[var13];
                            if (this.isDependent(beanName, dependsOnBean)) {
                                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                            }
                            //缓存依赖调用
                            this.registerDependentBean(dependsOnBean, beanName);
                            this.getBean(dependsOnBean);
                        }
                    }
                    //实例化依赖的bean后便可以实例化mbd本身
                    //singleton模式的创建
                    if (mbd.isSingleton()) {
                        sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                            public Object getObject() throws BeansException {
                                try {
                                    return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                                } catch (BeansException var2) {
                                    AbstractBeanFactory.this.destroySingleton(beanName);
                                    throw var2;
                                }
                            }
                        });
                        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    } else if (mbd.isPrototype()) {
                        //protoType模式的创建
                        var11 = null;
    
                        Object prototypeInstance;
                        try {
                            this.beforePrototypeCreation(beanName);
                            prototypeInstance = this.createBean(beanName, mbd, args);
                        } finally {
                            this.afterPrototypeCreation(beanName);
                        }
    
                        bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                    } else {
                        //指定的scope上实例化bean
                        String scopeName = mbd.getScope();
                        Scope scope = (Scope)this.scopes.get(scopeName);
                        if (scope == null) {
                            throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                        }
    
                        try {
                            Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                                public Object getObject() throws BeansException {
                                    AbstractBeanFactory.this.beforePrototypeCreation(beanName);
    
                                    Object var1;
                                    try {
                                        var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
                                    } finally {
                                        AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                                    }
    
                                    return var1;
                                }
                            });
                            bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                        } catch (IllegalStateException var21) {
                            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", var21);
                        }
                    }
                } catch (BeansException var23) {
                    this.cleanupAfterBeanCreationFailure(beanName);
                    throw var23;
                }
            }
            //检查需要的类型是否符合bean的实际类型
            if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
                try {
                    return this.getTypeConverter().convertIfNecessary(bean, requiredType);
                } catch (TypeMismatchException var22) {
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);
                    }
    
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            } else {
                return bean;
            }
        }

    从上述代码可以看出bean的加载经历了一个复杂的过程,以上仅能粗略的了解整个Spring加载bean的过程。加载的步骤大致如下

    1:转换对应的beanName

    因为传入的参数不仅是beanName也可能是别名,也可能是FactoryBean,所以需要解析:去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&而使name="aa"。

    取指定alias所表示的最终beanName,例如别名A指向名称B的bean则返回B;

    2:尝试从缓存中加载单例

    单例在spring容器内只会创建一次,后续获取都是从单例缓存中获取。如果获取不到则从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建的时候为了

    避免循环依赖,在Spring中创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory

    3:bean的实例化

    如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。

    4:原型模式的依赖检查

    只有在单例情况下才会尝试解决循环依赖

    5:加测parentBeanFactory

    如果缓存中没有取到则直接转到父类工厂上加载。

    6:将存储xml配置文件的GernericBeanDefinition转换为RootBeanDefinition

    7:寻找依赖

    8:针对不同的scope进行bean的创建

    9:类型转换

    缓存池获取bean实例

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //一级缓存:存放的是已经完成实例化,属性填充和初始化步骤的单例bean实例
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                //二级缓存:存放的是提前暴露的单例bean实例,可能是代理对象,也可能是未经代理的原对象,但都还没有完成初始化的步骤
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    //三级缓存:存放的是ObjectFactory的匿名内部类实例
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //回调ObjectFactory#getObject方法获取提前暴露的引用
                        singletonObject = singletonFactory.getObject();
                        //移入二级缓存
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        //移除三级缓存
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject != NULL_OBJECT ? singletonObject : null;
    }
  • 相关阅读:
    CS229 6.4 Neurons Networks Autoencoders and Sparsity
    CS229 6.3 Neurons Networks Gradient Checking
    【Leetcode】【Easy】Min Stack
    【Leetcode】【Easy】Merge Sorted Array
    【Leetcode】【Easy】ZigZag Conversion
    【Leetcode】【Easy】Valid Palindrome
    【Leetcode】【Easy】Reverse Integer
    【Leetcode】【Easy】Palindrome Number
    【Leetcode】【Easy】Length of Last Word
    【Leetcode】【Easy】Remove Nth Node From End of List
  • 原文地址:https://www.cnblogs.com/chenpt/p/13718381.html
Copyright © 2020-2023  润新知