深入源码分析SpringIOC(二)

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 深入源码分析SpringIOC(二)

IOC之Bean的初始化(实例化与依赖注入)

文章目录

    • - -
      • - - -

        -

        -

         

        前情概要

        回顾之前的内容IOC初始化之准备工作(定位、加载、注册) ,说到在 ApplicationContext初始化时,会先去根据资源路径去定位、加载并且注册Bean信息到 BeanFactory中,但此过程并未实例化,在结尾也说了,在调用BeanFactorygetBean方法时Bean才会真正实例化。那么在 ApplicationContext中是什么时候去初始化Bean的呢?回顾一下refresh方法:

        1234567891011121314151617
        @Overridepublic void refresh() throws BeansException, IllegalStateException {    synchronized (this.startupShutdownMonitor) {         // Tell the subclass to refresh the internal bean factory.        //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从        //子类的refreshBeanFactory()方法启动        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();         //略...         // Instantiate all remaining (non-lazy-init) singletons.        //初始化所有剩余的单例Bean        finishBeanFactoryInitialization(beanFactory);         //略...}

        @Override
        public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {

        
            // Tell the subclass to refresh the internal bean factory.
            //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
            //子类的refreshBeanFactory()方法启动
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            
            //略...
            
            // Instantiate all remaining (non-lazy-init) singletons.
            //初始化所有剩余的单例Bean
            finishBeanFactoryInitialization(beanFactory);
        
            //略...
        

        }

        由refresh方法可知, ApplicationContext将在方法接近末尾的时候去初始化Bean,但不是初始化所有Bean,而是作用域为singleton单例的且配置lazy-init=false才会进行初始化Bean的操作。

        123456789
        //对配置了lazy-init属性的Bean进行预实例化处理protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {     //略...     // Instantiate all remaining (non-lazy-init) singletons.    //对配置了lazy-init属性的单态模式Bean进行预实例化处理    beanFactory.preInstantiateSingletons();}

        //对配置了lazy-init属性的Bean进行预实例化处理
        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

        
        //略...
        
        // Instantiate all remaining (non-lazy-init) singletons.
        //对配置了lazy-init属性的单态模式Bean进行预实例化处理
        beanFactory.preInstantiateSingletons();
        

        }

        注意这里初始化方法还是委托给了我们上一篇文章说的BeanFactory去做,而不是 ApplicationContext,对于很多操作Bean的场景大部分都是由 DefaultListableBeanFactory去做。

        12345678910111213141516171819202122232425262728293031323334353637383940414243444546
        //对配置lazy-init属性单态Bean的预实例化@Overridepublic void preInstantiateSingletons() throws BeansException {     // 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.    ListString beanNames = new ArrayList(this.beanDefinitionNames);     // Trigger initialization of all non-lazy singleton beans...    //遍历所有的beanNames    for (String beanName : beanNames) {        //获取指定名称的Bean定义        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);        //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {            //如果指定名称的bean是创建容器的Bean            if (isFactoryBean(beanName)) {                //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号                //时,获取的是产生容器对象本身,而不是容器产生的Bean.                //调用getBean方法,触发容器对Bean实例化和依赖注入过程                final FactoryBean? factory = (FactoryBean?) getBean(FACTORY_BEAN_PREFIX + beanName);                //标识是否需要预实例化                boolean isEagerInit;                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                    //一个匿名内部类                    isEagerInit = AccessController.doPrivileged((PrivilegedActionBoolean) () -                                                                ((SmartFactoryBean?) factory).isEagerInit(),                                                                getAccessControlContext());                }                else {                    isEagerInit = (factory instanceof SmartFactoryBean &&                                   ((SmartFactoryBean?) factory).isEagerInit());                }                if (isEagerInit) {                    //调用getBean方法,触发容器对Bean实例化和依赖注入过程                    getBean(beanName);                }            }            else {                getBean(beanName);            }        }    }     //略...}

        //对配置lazy-init属性单态Bean的预实例化
        @Override
        public void preInstantiateSingletons() throws BeansException {

        
        // 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.
        ListString beanNames = new ArrayList(this.beanDefinitionNames);
        
        // Trigger initialization of all non-lazy singleton beans...
        //遍历所有的beanNames
        for (String beanName : beanNames) {
            //获取指定名称的Bean定义
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //如果指定名称的bean是创建容器的Bean
                if (isFactoryBean(beanName)) {
                    //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号
                    //时,获取的是产生容器对象本身,而不是容器产生的Bean.
                    //调用getBean方法,触发容器对Bean实例化和依赖注入过程
                    final FactoryBean? factory = (FactoryBean?) getBean(FACTORY_BEAN_PREFIX + beanName);
                    //标识是否需要预实例化
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        //一个匿名内部类
                        isEagerInit = AccessController.doPrivileged((PrivilegedActionBoolean) () -
                                                                    ((SmartFactoryBean?) factory).isEagerInit(),
                                                                    getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                       ((SmartFactoryBean?) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        //调用getBean方法,触发容器对Bean实例化和依赖注入过程
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
        
        //略...
        

        }

        可以看到,这里会遍历所有的Bean,如果是单例且lazy-init=false才会进行初始化,而真正初始化的工作将从getBean方法 中展开。

        初始化Bean

        在BeanFactory继承体系结构中,可以看到 AbstractBeanFactory这个抽象类实现了BeanFactory接口,自然在这个抽象类中会实现getBean方法:

        123456
        //获取IOC容器中指定名称的Bean@Overridepublic Object getBean(String name) throws BeansException {    //doGetBean才是真正向IoC容器获取被管理Bean的过程    return doGetBean(name, null, null, false);}

        //获取IOC容器中指定名称的Bean
        @Override
        public Object getBean(String name) throws BeansException {
        //doGetBean才是真正向IoC容器获取被管理Bean的过程
        return doGetBean(name, null, null, false);
        }

        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
        //真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方protected T T doGetBean(final String name, @Nullable final ClassT requiredType,                          @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {     //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖    //如果指定的是别名,将别名转换为规范的Bean名称    final String beanName = transformedBeanName(name);    Object bean;     // Eagerly check singleton cache for manually registered singletons.    //先从缓存中取是否已经有被创建过的单态类型的Bean    //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建    Object sharedInstance = getSingleton(beanName);    //IOC容器创建单例模式Bean实例对象    if (sharedInstance != null && args == null) {        if (logger.isDebugEnabled()) {            //如果指定名称的Bean在容器中已有单例模式的Bean被创建            //直接返回已经创建的Bean            if (isSingletonCurrentlyInCreation(beanName)) {                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +                             "' that is not fully initialized yet - a consequence of a circular reference");            }            else {                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");            }        }        //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理        //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是        //创建创建对象的工厂Bean,两者之间有区别        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);    }     else {        // Fail if we're already creating this bean instance:        // We're assumably within a circular reference.        //缓存没有正在创建的单例模式Bean        //缓存中已经有已经创建的原型模式Bean        //但是由于循环引用的问题导致实例化对象失败        if (isPrototypeCurrentlyInCreation(beanName)) {            throw new BeanCurrentlyInCreationException(beanName);        }         // Check if bean definition exists in this factory.        //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否        //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器        //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找        BeanFactory parentBeanFactory = getParentBeanFactory();        //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {            // Not found - check parent.            //解析指定Bean名称的原始名称            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 {                // No args - delegate to standard getBean method.                //委派父级容器根据指定名称和类型查找                return parentBeanFactory.getBean(nameToLookup, requiredType);            }        }         //创建的Bean是否需要进行类型验证,一般不需要        if (!typeCheckOnly) {            //向容器标记指定的Bean已经被创建            markBeanAsCreated(beanName);        }         try {            //根据指定Bean名称获取其父级的Bean定义            //主要解决Bean继承时子类合并父类公共属性问题            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);            checkMergedBeanDefinition(mbd, beanName, args);             // Guarantee initialization of beans that the current bean depends on.            //获取当前Bean所有依赖Bean的名称            String[] dependsOn = mbd.getDependsOn();            //如果当前Bean有依赖Bean            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 + "'");                    }                    //递归调用getBean方法,获取当前Bean的依赖Bean                    registerDependentBean(dep, beanName);                    //把被依赖Bean注册给当前依赖的Bean                    getBean(dep);                }            }             // Create bean instance.            //创建单例模式Bean的实例对象            if (mbd.isSingleton()) {                //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象                sharedInstance = getSingleton(beanName, () - {                    try {                        //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义                        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.                        //显式地从容器单例模式Bean缓存中清除实例对象                        destroySingleton(beanName);                        throw ex;                    }                });                //获取给定Bean的实例对象                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);            }             //IOC容器创建原型模式Bean实例对象            else if (mbd.isPrototype()) {                // It's a prototype - create a new instance.                //原型模式(Prototype)是每次都会创建一个新的对象                Object prototypeInstance = null;                try {                    //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象                    beforePrototypeCreation(beanName);                    //创建指定Bean对象实例                    prototypeInstance = createBean(beanName, mbd, args);                }                finally {                    //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建                    afterPrototypeCreation(beanName);                }                //获取给定Bean的实例对象                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);            }             //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中            //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中            //比较常用,如:request、session、application等生命周期            else {                String scopeName = mbd.getScope();                final Scope scope = this.scopes.get(scopeName);                //Bean定义资源中没有配置生命周期范围,则Bean定义不合法                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的实例对象                    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.    //对创建的Bean实例对象进行类型检查    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.isDebugEnabled()) {                logger.debug("Failed to convert bean '" + name + "' to required type '" +                             ClassUtils.getQualifiedName(requiredType) + "'", ex);            }            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());        }    }    return (T) bean;}

        //真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
        protected T doGetBean(final String name, @Nullable final Class requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        
        //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
        //如果指定的是别名,将别名转换为规范的Bean名称
        final String beanName = transformedBeanName(name);
        Object bean;
        
        // Eagerly check singleton cache for manually registered singletons.
        //先从缓存中取是否已经有被创建过的单态类型的Bean
        //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建
        Object sharedInstance = getSingleton(beanName);
        //IOC容器创建单例模式Bean实例对象
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                //如果指定名称的Bean在容器中已有单例模式的Bean被创建
                //直接返回已经创建的Bean
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                 "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
            //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
            //创建创建对象的工厂Bean,两者之间有区别
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        
        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            //缓存没有正在创建的单例模式Bean
            //缓存中已经有已经创建的原型模式Bean
            //但是由于循环引用的问题导致实例化对象失败
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
        
            // Check if bean definition exists in this factory.
            //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
            //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
            //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found - check parent.
                //解析指定Bean名称的原始名称
                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 {
                    // No args - delegate to standard getBean method.
                    //委派父级容器根据指定名称和类型查找
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
        
            //创建的Bean是否需要进行类型验证,一般不需要
            if (!typeCheckOnly) {
                //向容器标记指定的Bean已经被创建
                markBeanAsCreated(beanName);
            }
        
            try {
                //根据指定Bean名称获取其父级的Bean定义
                //主要解决Bean继承时子类合并父类公共属性问题
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
        
                // Guarantee initialization of beans that the current bean depends on.
                //获取当前Bean所有依赖Bean的名称
                String[] dependsOn = mbd.getDependsOn();
                //如果当前Bean有依赖Bean
                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 + "'");
                        }
                        //递归调用getBean方法,获取当前Bean的依赖Bean
                        registerDependentBean(dep, beanName);
                        //把被依赖Bean注册给当前依赖的Bean
                        getBean(dep);
                    }
                }
        
                // Create bean instance.
                //创建单例模式Bean的实例对象
                if (mbd.isSingleton()) {
                    //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
                    sharedInstance = getSingleton(beanName, () - {
                        try {
                            //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
                            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.
                            //显式地从容器单例模式Bean缓存中清除实例对象
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    //获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
        
                //IOC容器创建原型模式Bean实例对象
                else if (mbd.isPrototype()) {
                    // It's a prototype - create a new instance.
                    //原型模式(Prototype)是每次都会创建一个新的对象
                    Object prototypeInstance = null;
                    try {
                        //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象
                        beforePrototypeCreation(beanName);
                        //创建指定Bean对象实例
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建
                        afterPrototypeCreation(beanName);
                    }
                    //获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
        
                //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
                //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
                //比较常用,如:request、session、application等生命周期
                else {
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    //Bean定义资源中没有配置生命周期范围,则Bean定义不合法
                    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的实例对象
                        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.
        //对创建的Bean实例对象进行类型检查
        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.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                 ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
        

        }

        在doGetBean方法中,其实做了很多事,这里一一解释:

        1. 首先调用 getSingleton(beanName); 方法,先尝试获取一个单例实例,这个方法解决了循环依赖的问题,下面我会详细的说明。
        2. 如果尝试获取的实例不存在当前IOC容器,如果父容器不为空会去父容器中获取Bean。
        3. 经过以上步骤都没有获取到Bean实例的话,先寻找所有依赖的Bean,对依赖的Bean循环调用getBean()方法(依赖Bean有可能为单例,此时如果是单例Bean的话这样做的目的第一是先将此Bean初始化,第二是会将其缓存下来,等之后依赖注入会用到)
          • 如果是单例Bean:调用getSingleton方法,其第二个参数 ObjectFactory是一个功能接口,里面有一个模板提供方法,getObject,调用方法返回实例,所以在外面调用getSingleton方法时使用匿名类方式将子类createBean方法赋给 ObjectFactory对象的getObject方法,便于在getSingleton方法中可以调用。这里是一个面向函数式编程思想 。这里多一层getSingleton方法是为了解决循环依赖问题 ,下面会详细解释。
          • 如果是原型Bean:直接调用子类createBean方法,因为其不需要经过一些循环依赖步骤,换言之,如果有原型Bean循环依赖了,是不能解决的,会抛出异常。
          • 如果是其他scope的Bean:会设置其scope,然后同样是调用createBean去创建。

        到这里我们应该要明白了,真正去创建Bean的方法是createBean

        12345678910111213141516171819202122232425262728293031323334353637383940414243444546
        //创建Bean实例对象@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)    throws BeanCreationException {     if (logger.isDebugEnabled()) {        logger.debug("Creating instance of bean '" + beanName + "'");    }    RootBeanDefinition mbdToUse = mbd;     // Make sure bean class is actually resolved at this point, and    // clone the bean definition in case of a dynamically resolved Class    // which cannot be stored in the shared merged bean definition.    //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载    Class? resolvedClass = resolveBeanClass(mbd, beanName);    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {        mbdToUse = new RootBeanDefinition(mbd);        mbdToUse.setBeanClass(resolvedClass);    }     //略...     try {        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.        //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);        if (bean != null) {            return bean;        }    }    catch (Throwable ex) {        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,                                        "BeanPostProcessor before instantiation of bean failed", ex);    }     try {        //创建Bean的入口        Object beanInstance = doCreateBean(beanName, mbdToUse, args);        if (logger.isDebugEnabled()) {            logger.debug("Finished creating instance of bean '" + beanName + "'");        }        return beanInstance;    }     //略...}

        //创建Bean实例对象
        @Override
        protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

        
        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
        
        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
        Class? resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
        
        //略...
        
        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                            "BeanPostProcessor before instantiation of bean failed", ex);
        }
        
        try {
            //创建Bean的入口
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        
        //略...
        

        }

        这里也分步骤进行解读:

        1. 首先会先判断此Bean是否可以实例化。
        2. 然后此时会调用resolveBeforeInstantiation方法,这是一个通知回调方法,会将此时的Bean的Class与BeanName传入容器中实现了 InstantiationAwareBeanPostProcessor接口的方法postProcessBeforeInstantiation。举个例子 AbstractAutoProxyCreator这个类实现了 BeanPostProcessor这个接口来完成AOP代理,但它同时也实现了 InstantiationAwareBeanPostProcessor这个接口,这个接口的方法调用时间即为上述Bean实例化与依赖注入之前(doCreateBean 才真正进行Bean实例化与依赖注入)。如果关于 BeanPostProcessor的知识不懂的话,可以看看下一章我会讲到Spring的自定义扩展方式,然后下下章讲到AOP的时候也会详细讲解 AbstractAutoProxyCreator实现 InstantiationAwareBeanPostProcessor接口的真正作用,这里读者只要记住, InstantiationAwareBeanPostProcessor的调用时机是在Bean实例化以前。
        3. 如果此时 InstantiationAwareBeanPostProcessor的回调方法没有获取到Bean(自定义扩展的内容,说明没有进行自定义扩展),那么进入真正创建Bean的方法doCreateBean
          123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
          //真正创建Bean的方法protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)    throws BeanCreationException {     // Instantiate the bean.    //封装被创建的Bean对象    BeanWrapper instanceWrapper = null;    if (mbd.isSingleton()) {        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);    }    if (instanceWrapper == null) {        instanceWrapper = createBeanInstance(beanName, mbd, args);    }    final Object bean = instanceWrapper.getWrappedInstance();    //获取实例化对象的类型    Class? beanType = instanceWrapper.getWrappedClass();    if (beanType != NullBean.class) {        mbd.resolvedTargetType = beanType;    }     // Allow post-processors to modify the merged bean definition.    //调用PostProcessor后置处理器    synchronized (mbd.postProcessingLock) {        if (!mbd.postProcessed) {            try {                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);            }            catch (Throwable ex) {                throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                                "Post-processing of merged bean definition failed", ex);            }            mbd.postProcessed = true;        }    }     // Eagerly cache singletons to be able to resolve circular references    // even when triggered by lifecycle interfaces like BeanFactoryAware.    //向容器中缓存单例模式的Bean对象,以防循环引用    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&                                      isSingletonCurrentlyInCreation(beanName));    if (earlySingletonExposure) {        if (logger.isDebugEnabled()) {            logger.debug("Eagerly caching bean '" + beanName +                         "' to allow for resolving potential circular references");        }        //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用        addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));    }     // Initialize the bean instance.    //Bean对象的初始化,依赖注入在此触发    //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean    Object exposedObject = bean;    try {        //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象        populateBean(beanName, mbd, instanceWrapper);        //初始化Bean对象        exposedObject = initializeBean(beanName, exposedObject, mbd);    }    catch (Throwable ex) {        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {            throw (BeanCreationException) ex;        }        else {            //抛异常..略...        }    }     if (earlySingletonExposure) {        //获取指定名称的已注册的单例模式Bean对象        Object earlySingletonReference = getSingleton(beanName, false);        if (earlySingletonReference != null) {            //根据名称获取的已注册的Bean和正在实例化的Bean是同一个            if (exposedObject == bean) {                //当前实例化的Bean初始化完成                exposedObject = earlySingletonReference;            }            //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {                String[] dependentBeans = getDependentBeans(beanName);                SetString actualDependentBeans = new LinkedHashSet(dependentBeans.length);                //获取当前Bean所依赖的其他Bean                for (String dependentBean : dependentBeans) {                    //对依赖Bean进行类型检查                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                        actualDependentBeans.add(dependentBean);                    }                }                 //略...             }        }    }     // Register bean as disposable.    //注册完成依赖注入的Bean    try {        registerDisposableBeanIfNecessary(beanName, bean, mbd);    }    catch (BeanDefinitionValidationException ex) {        throw new BeanCreationException(            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);    }     return exposedObject;}

        //真正创建Bean的方法
        protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

        
        // Instantiate the bean.
        //封装被创建的Bean对象
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        //获取实例化对象的类型
        Class? beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
        
        // Allow post-processors to modify the merged bean definition.
        //调用PostProcessor后置处理器
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                    "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
        
        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        //向容器中缓存单例模式的Bean对象,以防循环引用
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                          isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                             "' to allow for resolving potential circular references");
            }
            //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
            addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));
        }
        
        // Initialize the bean instance.
        //Bean对象的初始化,依赖注入在此触发
        //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
        Object exposedObject = bean;
        try {
            //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
            populateBean(beanName, mbd, instanceWrapper);
            //初始化Bean对象
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                //抛异常..略...
            }
        }
        
        if (earlySingletonExposure) {
            //获取指定名称的已注册的单例模式Bean对象
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                //根据名称获取的已注册的Bean和正在实例化的Bean是同一个
                if (exposedObject == bean) {
                    //当前实例化的Bean初始化完成
                    exposedObject = earlySingletonReference;
                }
                //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    SetString actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    //获取当前Bean所依赖的其他Bean
                    for (String dependentBean : dependentBeans) {
                        //对依赖Bean进行类型检查
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    
                    //略...
                    
                }
            }
        }
        
        // Register bean as disposable.
        //注册完成依赖注入的Bean
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
        
        return exposedObject;
        

        }

        1. 创建完成的Bean实例,其实又被Spring封装了一层,最终封装Bean为 BeanWrapper,此封装类存放Bean实例对象、Bean的Class类型等。createBeanInstance(beanName, mbd, args) 方法会实例化Bean,并且封装成 BeanWrapper返回。注意此时仅仅只是调用构造器实例化Bean而已。
        2. 在实例化Bean之后,如果该Bean是单例且允许循环依赖(可在配置中配置此属性),在此为了解决循环引用,提前将对象引用暴露出来,下面会提到循环引用的解决方法。
        3. 到这里Bean已经实例化好了,接下来调用populateBean(beanName, mbd, instanceWrapper) 方法进行依赖注入。
        4. 此时的Bean已是实例化且依赖注入好的Bean,接着会调用initializeBean(beanName, exposedObject, mbd) 方法,该方法是一个回调通知方法,在扩展Spring中会详细解释,这里只要记住,在这个时机Spring提供出了一个回调方法可供扩展。
        5. 调用 registerDisposableBeanIfNecessary(beanName, bean, mbd); 方法注册此Bean。

        解决循环依赖的问题

        什么是循环依赖?

        假设aBean中需要依赖bBean,而bBean中也需要依赖aBean,这时初始化aBean时,需要进行依赖注入,所以需要初始化bBean,而在bBean初始化时又需要依赖注入,此时需要一个aBean,这就造成了一个死锁,aBean在等待bBean初始化好,才能完成aBean的初始化,而bBean又在等待aBean初始化好,才能完成bBean的初始化,那么在Spring中是如何解决这种循环依赖问题的呢?

        Spring中如何解决循环依赖

        让我们回顾一下时序,我们先是调用了getBean方法,接着调用doGetBean方法真正去获取Bean,不知读者是否还记得,此时会先去调用getSingleton(beanName) 方法,尝试获取一个单例实例:

        123456789101112131415161718192021222324252627
        @Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {    //尝试先从singletonObjects获取实例    Object singletonObject = this.singletonObjects获取实例.get(beanName);    //如果singletonObjects没有存放此Bean的实例的话,获取早期暴露的实例    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {        synchronized (this.singletonObjects) {            //先尝试从早期暴露缓存earlySingletonObjects中获取            singletonObject = this.earlySingletonObjects.get(beanName);            //早期暴露的缓存没有的话,去早期暴露的Map中获取            if (singletonObject == null && allowEarlyReference) {                //singletonFactories此Map即为早期暴露的Map                ObjectFactory? singletonFactory = this.singletonFactories.get(beanName);                //如果可以获取到早期暴露的对象的话                if (singletonFactory != null) {                    //从此singletonFactory中获取Bean实例                    singletonObject = singletonFactory.getObject();                    //存放在早期暴露的缓存中,下次取只需要从earlySingletonObjects拿即可                    this.earlySingletonObjects.put(beanName, singletonObject);                    //由于已经存放在缓存中,singletonFactories继续存放没有意义,移除                    this.singletonFactories.remove(beanName);                }            }        }    }    return singletonObject;}

        @Nullable
        protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //尝试先从singletonObjects获取实例
        Object singletonObject = this.singletonObjects获取实例.get(beanName);
        //如果singletonObjects没有存放此Bean的实例的话,获取早期暴露的实例
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
        //先尝试从早期暴露缓存earlySingletonObjects中获取
        singletonObject = this.earlySingletonObjects.get(beanName);
        //早期暴露的缓存没有的话,去早期暴露的Map中获取
        if (singletonObject == null && allowEarlyReference) {
        //singletonFactories此Map即为早期暴露的Map
        ObjectFactory? singletonFactory = this.singletonFactories.get(beanName);
        //如果可以获取到早期暴露的对象的话
        if (singletonFactory != null) {
        //从此singletonFactory中获取Bean实例
        singletonObject = singletonFactory.getObject();
        //存放在早期暴露的缓存中,下次取只需要从earlySingletonObjects拿即可
        this.earlySingletonObjects.put(beanName, singletonObject);
        //由于已经存放在缓存中,singletonFactories继续存放没有意义,移除
        this.singletonFactories.remove(beanName);
        }
        }
        }
        }
        return singletonObject;
        }

        此时读者需要记住几个Map,关注接下来的方法它们的put时机和put的value到底是什么:

        1. singletonObjects:存放单例Bean的一个Map。
        2. earlySingletonObjects :早期暴露的缓存,在获取早期暴露对象之后会进行缓存。
        3. singletonFactories :关键解决了循环依赖问题的一个Map对象,方式是过早暴露Bean引用。需要关注的点是它的value是一个 ObjectFactory对象,此时依然是面向函数式编程 ,此接口只是一个功能暴露接口,也就是最终调用singletonFactory.getObject(); 的方法为关键,该方法获取早期Bean实例。

        接着回忆一下,在尝试调用getSingleton方法未获得对象时,会判断是否为单例,如果Bean为单例则会调用getSingleton(String beanName, ObjectFactory? singletonFactory) 方法,注意此时的方法与上面的参数不一样,重载方法:

        12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
        public Object getSingleton(String beanName, ObjectFactory? singletonFactory) {    Assert.notNull(beanName, "Bean name must not be null");    //此过程需要进行同步处理    synchronized (this.singletonObjects) {        //依然先尝试从singletonObjects中获取        Object singletonObject = this.singletonObjects.get(beanName);        //获取不到的话        if (singletonObject == null) {            //如果此时单例Bean已经是在创建了,由于是单例的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 + "'");            }            //此时就是上述提到的创建Bean的标识,在此标记此Bean已经正在创建            beforeSingletonCreation(beanName);            boolean newSingleton = false;            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);            if (recordSuppressedExceptions) {                this.suppressedExceptions = new LinkedHashSet();            }            try {                //面向函数编程,调用功能接口中的方法获取单例Bean,getObject方法的实现                //在调用getSingleton之前就已经使用匿名类的方式传入                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;                }                //此时移除Bean创建的标识,表示此Bean不在创建时间了,已经创建完成                afterSingletonCreation(beanName);            }            if (newSingleton) {                //此时会将创建好了的Bean存入单例Map中                addSingleton(beanName, singletonObject);            }        }        return singletonObject;    }}

        public Object getSingleton(String beanName, ObjectFactory? singletonFactory) {
        Assert.notNull(beanName, “Bean name must not be null”);
        //此过程需要进行同步处理
        synchronized (this.singletonObjects) {
        //依然先尝试从singletonObjects中获取
        Object singletonObject = this.singletonObjects.get(beanName);
        //获取不到的话
        if (singletonObject == null) {
        //如果此时单例Bean已经是在创建了,由于是单例的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 + “‘“);
        }
        //此时就是上述提到的创建Bean的标识,在此标记此Bean已经正在创建
        beforeSingletonCreation(beanName);
        boolean newSingleton = false;
        boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
        if (recordSuppressedExceptions) {
        this.suppressedExceptions = new LinkedHashSet();
        }
        try {
        //面向函数编程,调用功能接口中的方法获取单例Bean,getObject方法的实现
        //在调用getSingleton之前就已经使用匿名类的方式传入
        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;
        }
        //此时移除Bean创建的标识,表示此Bean不在创建时间了,已经创建完成
        afterSingletonCreation(beanName);
        }
        if (newSingleton) {
        //此时会将创建好了的Bean存入单例Map中
        addSingleton(beanName, singletonObject);
        }
        }
        return singletonObject;
        }
        }

        123456789101112
        protected void addSingleton(String beanName, Object singletonObject) {    //需要同步处理    synchronized (this.singletonObjects) {        //加入singletonObjects以供后续getBean时直接获取实例        this.singletonObjects.put(beanName, singletonObject);        //将早期暴露的实例移除,就算不移除这里也没有用了,因为根本不会有进入此Map的时机        this.singletonFactories.remove(beanName);        //这里就更不用说了,不会有进入此Map的时机        this.earlySingletonObjects.remove(beanName);        this.registeredSingletons.add(beanName);    }}

        protected void addSingleton(String beanName, Object singletonObject) {
        //需要同步处理
        synchronized (this.singletonObjects) {
        //加入singletonObjects以供后续getBean时直接获取实例
        this.singletonObjects.put(beanName, singletonObject);
        //将早期暴露的实例移除,就算不移除这里也没有用了,因为根本不会有进入此Map的时机
        this.singletonFactories.remove(beanName);
        //这里就更不用说了,不会有进入此Map的时机
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
        }
        }

        由于此时已经将完整的Bean(实例化以及依赖注入完成)创建出来了,所以直接放入singletonObjects这个Map中,以供后续getBean时就可以直接取出。如果你还记得上面我让你记住的那几个Map的话,此时你应该可以有一个承上启下的感觉,singletonObjects是在初始化Bean完成时才会put实例

        此时我们回到创建单例Bean中:

        123456789101112131415161718192021
        // Create bean instance.//创建单例模式Bean的实例对象if (mbd.isSingleton()) {    //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象    sharedInstance = getSingleton(beanName, () - {        try {            //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义            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.            //显式地从容器单例模式Bean缓存中清除实例对象            destroySingleton(beanName);            throw ex;        }    });    //获取给定Bean的实例对象    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}

        // Create bean instance.
        //创建单例模式Bean的实例对象
        if (mbd.isSingleton()) {
        //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
        sharedInstance = getSingleton(beanName, () - {
        try {
        //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
        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.
        //显式地从容器单例模式Bean缓存中清除实例对象
        destroySingleton(beanName);
        throw ex;
        }
        });
        //获取给定Bean的实例对象
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }

        这里可以看得出来,此时将子类实现的createBean方法传入getSingleton中以供后续getObject调用,也就是说,真正创建Bean的方法是createBean(在上面说初始化的时候也有提到,所以这里只是提一下经过了哪些方法,不贴代码详细描述),而createBean中判断了一下此Bean是否可以实例化,接着调用真正干事情的doCreateBean方法去初始化Bean,此时会先调用构造器实例化此Bean,注意此时仅仅是实例化一个Bean对象出来,Bean实例还未依赖注入,此时会调用这样一段代码:

        1234567891011
        //向容器中缓存单例模式的Bean对象,以防循环引用boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&                                  isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {    if (logger.isDebugEnabled()) {        logger.debug("Eagerly caching bean '" + beanName +                     "' to allow for resolving potential circular references");    }    //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用    addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}

        //向容器中缓存单例模式的Bean对象,以防循环引用
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
        logger.debug(“Eagerly caching bean ‘“ + beanName +
        “‘ to allow for resolving potential circular references”);
        }
        //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
        addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));
        }

        上面也有说过,这里会判断是否为单例,且允许循环依赖,才会进入addSingletonFactory方法:

        12345678910111213
        protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {    Assert.notNull(singletonFactory, "Singleton factory must not be null");    //同步处理    synchronized (this.singletonObjects) {        //如果singletonObjects不存在该Bean才进行早期暴露        if (!this.singletonObjects.containsKey(beanName)) {            //会put一个功能接口对象到singletonFactories这个Map中            this.singletonFactories.put(beanName, singletonFactory);            this.earlySingletonObjects.remove(beanName);            this.registeredSingletons.add(beanName);        }    }}

        protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {
        Assert.notNull(singletonFactory, “Singleton factory must not be null”);
        //同步处理
        synchronized (this.singletonObjects) {
        //如果singletonObjects不存在该Bean才进行早期暴露
        if (!this.singletonObjects.containsKey(beanName)) {
        //会put一个功能接口对象到singletonFactories这个Map中
        this.singletonFactories.put(beanName, singletonFactory);
        this.earlySingletonObjects.remove(beanName);
        this.registeredSingletons.add(beanName);
        }
        }
        }

        此方法我称为一个早期暴露实例的方法,注意此时这里可以通过getEarlyBeanReference方法获得此时Bean的引用(Bean仅仅是实例化),然后将该方法传给 ObjectFactory这个功能接口的getObject方法,此时只需要将 ObjectFactory这个具有获取早期Bean引用的方法的对象put进singletonFactories这个Map中,读到这里,聪明的读者应该已经知道了Spring到底是如何解决循环依赖问题的了。

        循环依赖总结

        心中需要有一个时序图,你将会看的更清晰

        getBean - doGetBean - 先去singletonObjects这个Map中查看是否已经有Bean实例,如果没有 - 此Bean为单例的情况下,查看singletonFactories此Map是否有早期暴露的单例Bean引用 - 如果有证明此时这个单例Bean在其他地方已经在创建了,此时只需要返回此引用作为Bean实例即可。

        1. singletonObjects时机:会在完整创建完一个单例Bean时,存放起来,容器即为singletonObjects这个Map,并且会移除早期暴露 singletonFactories 这个Map中关于该Bean的引用。
        2. singletonFactories时机:在单例Bean情况下,在仅仅是实例化还未依赖注入此Bean时提前将Bean引用早期就存放在singletonFactories这个Map中,所以在doGetBean 尝试获取Bean实例时即可拿到一个Bean引用。

        此时就来回顾一下上述的循环依赖问题:

        当创建 aBean时,先去看看singletonObjects是否已经有实例,显然是没有,然后就会实例化此Bean,在这之后,依赖注入之前,将 aBean的引用存放在singletonFactories这个Map中,然后进行依赖注入,此时发现 aBean依赖 bBean,所以需要去初始化 bBean,依然是先看看singletonObjects是否有 bBean,显然也没有,然后就实例化 bBean,在 bBean依赖注入时,发现此 Bean依赖 aBean,所以又去初始化 aBean了,然后 aBean又去singletonObjects看是否存在实例,显然此时还是没有的,然后去singletonFactories这个Map查找的时候,发现存在一个Bean引用,所以获取该引用作为 aBean,将此引用注入到 bBean完成 bBean依赖注入的过程, bBean初始化结束,然后回到 aBean依赖注入,初始化 bBean成功,将 bBean注入到 aBean,然后 aBean初始化也成功,没有循环依赖问题。

        为什么早期暴露一个引用就可以解决循环依赖问题呢?

        还是看这个例子,在 bBean中注入的 aBean依赖仅仅是一个 aBean实例化之后还未依赖注入(不完整 aBean)引用,但当 aBean也初始化好了, bBean中的 aBean(此时是完整的aBean)不也初始化好了吗?因为引用指向的对象都是同一个地址,这样 bBean就能提前初始化好,只有 bBean初始化好了 aBean才能初始化好,所以解决了循环依赖的问题。

        但此时有一个问题,在上面介绍的所有的过程都是针对于单例Bean的,如果不是单例Bean根本都不会进行上述操作,如果是原型Bean循环依赖另一个原型Bean怎么办呢?目前我所知道的这个应该是解决不了的,在初始化的过程中就会报循环依赖的异常,所以要保证Bean为单例,才可以循环依赖。

        FactoryBean

        FactoryBean是Spring定义的一个特殊的Bean,先来看看它定义了什么方法:

        1234567891011121314151617
        //工厂Bean,用于产生其他对象public interface FactoryBeanT {     //获取容器管理的对象实例    @Nullable    T getObject() throws Exception;     //获取Bean工厂创建的对象的类型    @Nullable    Class? getObjectType();     //Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例    //对象,每次请求都返回同一个实例对象    default boolean isSingleton() {        return true;    }}

        //工厂Bean,用于产生其他对象
        public interface FactoryBean {

        
        //获取容器管理的对象实例
        @Nullable
        T getObject() throws Exception;
        
        //获取Bean工厂创建的对象的类型
        @Nullable
        Class? getObjectType();
        
        //Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例
        //对象,每次请求都返回同一个实例对象
        default boolean isSingleton() {
            return true;
        }
        

        }

        如果此Bean是FactoryBean,就必须实现FactoryBean接口。通过该接口可以看出FactoryBean的一些特性:

        1. getObeject:定义了一个获取Bean对象的方法。
        2. getObjectType:定义了一个获取Bean的Class对象的方法。
        3. isSingleton:判断此Factory生成的Bean是否为单例Bean,默认为true。

        FactoryBean是什么

        它是一个特殊的Bean,从名字就可以看出来,它是由Bean结尾的,意味着是一个Bean,但此Bean是工厂类型的Bean,什么意思呢?普通Bean只是IOC容器管理的真正代码中使用的对象,但工厂Bean不是我们要使用的对象,它负责生产真正的Bean,它是一个工厂,但它也是由工厂(BeanFactory)生产出来的,也就是说,FactroyBean是用来生产Bean而生的

        FactoryBean在IOC容器哪里用到

        BeanFactory接口中,定义了一个静态变量:

        123
        //对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,//如果需要得到工厂本身,需要转义String FACTORY_BEAN_PREFIX = "&";

        //对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
        //如果需要得到工厂本身,需要转义
        String FACTORY_BEAN_PREFIX = “&”;

        这个用处是用来区分要获取的是FactoryBean本身还是FactoryBean生产出来的Bean。假设有一个FactoryBean,BeanName=“demo”,你调用getBean方法希望获取到它的本身,你需要加一个符号:getBean(“&demo”),此时你get到的对象会是FactoryBean本身,如果不加此符号,会获取此FactoryBean的方法getObject生产出来的Bean作为返回值。没听懂?看看下面就懂了。

        回顾以上初始化Bean的过程,我们回到getBean之后的doGetBean这个一开始的起点方法中:

        123456789101112131415161718192021
        // Create bean instance.//创建单例模式Bean的实例对象if (mbd.isSingleton()) {    //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象    sharedInstance = getSingleton(beanName, () - {        try {            //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义            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.            //显式地从容器单例模式Bean缓存中清除实例对象            destroySingleton(beanName);            throw ex;        }    });    //获取给定Bean的实例对象    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}

        // Create bean instance.
        //创建单例模式Bean的实例对象
        if (mbd.isSingleton()) {
        //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
        sharedInstance = getSingleton(beanName, () - {
        try {
        //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
        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.
        //显式地从容器单例模式Bean缓存中清除实例对象
        destroySingleton(beanName);
        throw ex;
        }
        });
        //获取给定Bean的实例对象
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }

        这里举一个创建单例Bean过程的一段代码。我们上面介绍了createBean的流程,此时返回一个Bean是已经是实例化好了并且依赖注入完成,各种回调方法完成之后的一个Bean实例 sharedInstance,但是它没有真正的返回出去,而是又执行了一个方法getObjectForBeanInstance

        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
        //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理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.    //容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,    //也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,    //如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象    //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),    //且Bean实例也不是创建Bean实例对象的工厂Bean    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {        throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());    }     // 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.    //如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,    //调用者向获取对容器的引用,则直接返回当前的Bean实例    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {        return beanInstance;    }     //处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean    //使用工厂Bean创建一个Bean的实例对象    Object object = null;    if (mbd == null) {        //从Bean工厂缓存中获取给定名称的Bean实例对象        object = getCachedObjectForFactoryBean(beanName);    }    //让Bean工厂生产给定名称的Bean对象实例    if (object == null) {        // Return bean instance from factory.        FactoryBean? factory = (FactoryBean?) beanInstance;        // Caches object obtained from FactoryBean if it is a singleton.        //如果从Bean工厂生产的Bean是单态模式的,则缓存        if (mbd == null && containsBeanDefinition(beanName)) {            //从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性            mbd = getMergedLocalBeanDefinition(beanName);        }         boolean synthetic = (mbd != null && mbd.isSynthetic());        //调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,        //实现工厂Bean生产Bean对象实例的过程        object = getObjectFromFactoryBean(factory, beanName, !synthetic);    }    return object;}

        //获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
        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.
        //容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,
        //也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,
        //如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象
        //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),
        //且Bean实例也不是创建Bean实例对象的工厂Bean
        if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
        }
        
        // 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.
        //如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,
        //调用者向获取对容器的引用,则直接返回当前的Bean实例
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
            return beanInstance;
        }
        
        //处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean
        //使用工厂Bean创建一个Bean的实例对象
        Object object = null;
        if (mbd == null) {
            //从Bean工厂缓存中获取给定名称的Bean实例对象
            object = getCachedObjectForFactoryBean(beanName);
        }
        //让Bean工厂生产给定名称的Bean对象实例
        if (object == null) {
            // Return bean instance from factory.
            FactoryBean? factory = (FactoryBean?) beanInstance;
            // Caches object obtained from FactoryBean if it is a singleton.
            //如果从Bean工厂生产的Bean是单态模式的,则缓存
            if (mbd == null && containsBeanDefinition(beanName)) {
                //从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            //调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,
            //实现工厂Bean生产Bean对象实例的过程
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
        

        }

        也就是说,每一个Bean在初始化完成时,都会进入这个方法,这个方法会判断该Bean是否是FactoryBean,如果是的话,我们需要get的并不是这个FactoryBean,而是FactoryBean生产出来的Bean

        1. 先是判断get的名称是否为 “&” 符号开头,如果是的话就是指获取FactoryBean本身即可,但此Bean又没有实现FactoryBean,也就是说在不是FactoryBean的Bean上获取本身(”&”)将会抛出异常
        2. 再是判断该Bean如果不是FactoryBean,说明是普通Bean,直接返回本身即可,亦或是以”&”开头的,上面也说了,以“&”开头的话获取的是本身,所以也是直接返回本身即可。
        3. 如果程序运行到了这里,我们可以知道,此Bean是一个FactoryBean且并不是获取本身,而是获取FactoryBean生产出来的Bean,此时会先去FactoryBean缓存中获取是否有已经创建好了的Bean实例。
        4. 缓存如果有返回缓存即可,缓存没有就调用getObjectFromFactoryBean方法,从FactoryBean中生产Bean
          12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
          //Bean工厂生产Bean实例对象protected Object getObjectFromFactoryBean(FactoryBean? factory, String beanName, boolean shouldPostProcess) {    //Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象    if (factory.isSingleton() && containsSingleton(beanName)) {        //多线程同步,以防止数据不一致        synchronized (getSingletonMutex()) {            //直接从Bean工厂缓存中获取指定名称的Bean实例对象            Object object = this.factoryBeanObjectCache.get(beanName);            //Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象            if (object == null) {                //调用Bean工厂的getObject方法生产指定Bean的实例对象                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 {                    if (shouldPostProcess) {                        try {                            object = postProcessObjectFromFactoryBean(object, beanName);                        }                        catch (Throwable ex) {                            throw new BeanCreationException(beanName,                                                            "Post-processing of FactoryBean's singleton object failed", ex);                        }                    }                    //将生产的实例对象添加到Bean工厂缓存中                    this.factoryBeanObjectCache.put(beanName, object);                }            }            return object;        }    }    //调用Bean工厂的getObject方法生产指定Bean的实例对象    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;    }}

        //Bean工厂生产Bean实例对象
        protected Object getObjectFromFactoryBean(FactoryBean? factory, String beanName, boolean shouldPostProcess) {
        //Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象
        if (factory.isSingleton() && containsSingleton(beanName)) {
        //多线程同步,以防止数据不一致
        synchronized (getSingletonMutex()) {
        //直接从Bean工厂缓存中获取指定名称的Bean实例对象
        Object object = this.factoryBeanObjectCache.get(beanName);
        //Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象
        if (object == null) {
        //调用Bean工厂的getObject方法生产指定Bean的实例对象
        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 {
        if (shouldPostProcess) {
        try {
        object = postProcessObjectFromFactoryBean(object, beanName);
        }
        catch (Throwable ex) {
        throw new BeanCreationException(beanName,
        “Post-processing of FactoryBean’s singleton object failed”, ex);
        }
        }
        //将生产的实例对象添加到Bean工厂缓存中
        this.factoryBeanObjectCache.put(beanName, object);
        }
        }
        return object;
        }
        }
        //调用Bean工厂的getObject方法生产指定Bean的实例对象
        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;
        }
        }

        1. 首先判断FactoryBean生产的Bean是否为单例的,判断方法在FactoryBean接口中就已经定义此方法,并且要在熟悉的singletonObjects这个存放单例Bean的Map中存在此Bean,就可以判断生产的Bean为单例,所以需要缓存它,这个过程需要同步控制,接下来就调用doGetObjectFromFactoryBean方法去获取真正的Bean,并将其放入缓存中**factoryBeanObjectCache.put(beanName, object)**,以便下一次获取。然后返回真正生产出来的Bean。
        2. 此时如果走到这里,说明生产出来的Bean为非单例的,所以不需要缓存,只需要简单的调用doGetObjectFromFactoryBean方法去获取真正的Bean返回即可

        以上两种可能性都调用了同一个方法doGetObjectFromFactoryBean

        123456789101112131415
        //调用Bean工厂的getObject方法生产指定Bean的实例对象private Object doGetObjectFromFactoryBean(final FactoryBean? factory, final String beanName)    throws BeanCreationException {     Object object;     //安全验证,略...     //调用BeanFactory接口实现类的创建对象方法    object = factory.getObject();     //略...     return object;}

        //调用Bean工厂的getObject方法生产指定Bean的实例对象
        private Object doGetObjectFromFactoryBean(final FactoryBean? factory, final String beanName)
        throws BeanCreationException {

        
        Object object;
        
        //安全验证,略...
        
        //调用BeanFactory接口实现类的创建对象方法
        object = factory.getObject();
        
        //略...
        
        return object;
        

        }

        为了凸显出主线,我删减了一些支线代码,在这里可以看出来,最终调用的是FactoryBean的getObject方法,正是FactoryBean接口定义的这个方法,此方法为生产Bean的方法。

        FactoryBean例子

        为了加深理解,我举一个生产环境都会用到的一个FactoryBean来演示到底FactoryBean有什么用。

        这里我拿MyBatis与Spring整合包下的一个类 MapperFactoryBean作为例子讲解一下:

        123456789101112131415
        /**   * {@inheritDoc}   */@Overridepublic T getObject() throws Exception {    return getSqlSession().getMapper(this.mapperInterface);} /**   * {@inheritDoc}   */@Overridepublic boolean isSingleton() {    return true;}

        /**

        • {@inheritDoc}

        */
        @Override
        public T getObject() throws Exception {
        return getSqlSession().getMapper(this.mapperInterface);
        }

        /**

        • {@inheritDoc}

        */
        @Override
        public boolean isSingleton() {
        return true;
        }

        这里贴两个主要方法(需要有一点MyBatis的基础),我在分析MyBatis那篇文章中有提到,我们定义的那些Mapper接口,其实是SqlSession调用getMapper方法创建出来的,从以上getObject中可以看出, MapperFactoryBean是一个专门生产Mapper的一个FactoryBean,从isSingleton方法中可以看出,获取的Mapper都为单例。我们回忆一下在使用SSM的时候,如果是一个一个Mapper去配置成Bean放在IOC容器中,需要这样写:

        1234
        bean id="demoMapper" class="org.mybatis.Spring.mapper.MapperFactoryBean"    property name="mapperInterface" value="com.demo.DemoMapper"/property    property name="sqlSessionFactory" ref="sqlSessionFactory"/property/bean

        bean id=”demoMapper” class=”org.mybatis.Spring.mapper.MapperFactoryBean”
        property name=”mapperInterface” value=”com.demo.DemoMapper”/property
        property name=”sqlSessionFactory” ref=”sqlSessionFactory”/property
        /bean

        请注意,此Bean的class类型就是我们上面介绍的 MapperFactoryBean,其中有属性mapperInterface ,根据此属性去使用getObject方法获取真正的Mapper对象,就算你直接配置一个Mapper扫描路径,它的底层也是将扫描到的每一个mapper接口类型作为 MapperFactoryBean,以一个FactoryBean的形式存放在IOC容器中,当getBean的时候其实是调用 MapperFactoryBean这个FactoryBean的getObject方法:

        12
        @Autowiredprivate DemoMapper demoMapper

        @Autowired
        private DemoMapper demoMapper

        也就是说,你这样使用一个Mapper的时候,Spring容器其实是先获取 MapperFactoryBean,然后调用所有Bean都会调用的方法getObjectForBeanInstance去进行判断,发现此Bean为一个FactoryBean,调用此Bean的getObject方法,也就是委派其中的SqlSession去getMapper,从而获取真正的Mapper。

        总结

        到此就结束了初始化Bean的全过程,我们可以总结出来几件事:

        1. 在Spring中有一个特殊的单例模式,称为注册式单例,往Map中put那些Bean实例达到单例的效果(过程进行同步处理,解决并发问题)。
        2. 在初始化IOC容器时就会初始化Bean( 单例且lazy-init = false ),并将这些Bean存放在( BeanFactory的) Map中,这可以节省时间,一些单例Bean在启动时就已经创建好,使用时只需获取Map中实例即可。
        3. 与上一个类似的,如果Bean是除了单例之外的scope,在getBean时同样会走doCrateBean去创建实例,但区别在于不会对其进行缓存,也就是说,除单例之外的scope,可以达到每次getBean都是不同实例的Bean的效果。
        4. 循环依赖问题只在单例Bean 上被解决,原型Bean之间的循环依赖会抛出异常
        5. 在初始化Bean时多次出现回调通知方法,这个特性展现了Spring框架的易扩展性,这是非常强大的设计,将在下一章中对其进行讲解,AOP的实现也依赖于此。
        6. Factory是一个特殊的Bean ,主要用途是用来生产Bean的,请注意IOC容器中singletonObjects这个Map将会存放所有初始化好的单例Bean(包括那些单例的FactoryBean),而factoryBeanObjectCache存放的则是那些FactoryBean生产出来的Bean,也就是说,IOC容器不仅会存放FactoryBean在容器中,还会存放FactoryBean生产的Bean在容器中,双重缓存加快获取Bean的效率。这里读者要理清两者的关系。
  • 本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> 深入源码分析SpringIOC(二)