概述

后面咱们曾经剖析了spring对于xml配置文件的解析,将剖析的信息组装成 BeanDefinition,并将其保留注册到相应的 BeanDefinitionRegistry 中。至此,Spring IOC 的初始化工作实现。接下来咱们将对bean的加载进行摸索。

BeanFactory

当咱们显示或者隐式地调用 getBean() 时,则会触发加载 bean 阶段。如下:

public class AppTest {    @Test    public void MyTestBeanTest() {        BeanFactory bf = new XmlBeanFactory( new ClassPathResource("spring-config.xml"));        MyTestBean myTestBean = (MyTestBean) bf.getBean("myTestBean");    }}

咱们看到这个办法是在接口BeanFactory中定义的,咱们看下BeanFactory体系结构,如下图所示:

从上图咱们看到:  

(1)BeanFactory作为一个主接口不继承任何接口,暂且称为一级接口。

(2)有3个子接口继承了它,进行性能上的加强。这3个子接口称为二级接口。

(3)ConfigurableBeanFactory能够被称为三级接口,对二级接口HierarchicalBeanFactory进行了再次加强,它还继承了另一个外来的接口SingletonBeanRegistry

(4)ConfigurableListableBeanFactory是一个更弱小的接口,继承了上述的所有接口,无所不包,称为四级接口。(这4级接口是BeanFactory的根本接口体系。

(5)AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分性能。

(6)AbstractAutowireCapableBeanFactory同样是抽象类,继承自AbstractBeanFactory,并额定实现了二级接口AutowireCapableBeanFactory

(7)DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最弱小的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类。

(8)最初是最弱小的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些性能,使本人更弱小。

定义

BeanFactory,以Factory结尾,示意它是一个工厂类(接口), 它负责生产和治理bean的一个工厂。在Spring中,BeanFactory是IOC容器的外围接口,它的职责包含:实例化、定位、配置应用程序中的对象及建设这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,然而Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是罕用的一个,该实现将以XML形式形容组成利用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个齐全可配置的零碎或利用。

BeanFactory是Spring IOC容器的鼻祖,是IOC容器的根底接口,所有的容器都是从它这里继承实现而来。可见其位置。BeanFactory提供了最根本的IOC容器的性能,即所有的容器至多须要实现的规范。

XmlBeanFactory,只是提供了最根本的IOC容器的性能。而且XMLBeanFactory,继承自DefaultListableBeanFactory。DefaultListableBeanFactory理论蕴含了根本IOC容器所具备的所有重要性能,是一个残缺的IOC容器。

ApplicationContext蕴含BeanFactory的所有性能,通常倡议比BeanFactory优先。

BeanFactory体系结构是典型的工厂办法模式,即什么样的工厂生产什么样的产品。BeanFactory是最根本的形象工厂,而其余的IOC容器只不过是具体的工厂,对应着各自的Bean定义方法。但同时,其余容器也针对具体场景不同,进行了裁减,提供具体的服务。 如下:

Resource resource = new FileSystemResource("beans.xml");BeanFactory factory = new XmlBeanFactory(resource);ClassPathResource resource = new ClassPathResource("beans.xml");BeanFactory factory = new XmlBeanFactory(resource);ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"});BeanFactory factory = (BeanFactory) context;

根本就是这些了,接着应用getBean(String beanName)办法就能够获得bean的实例;BeanFactory提供的办法及其简略,仅提供了六种办法供客户调用:

  • boolean containsBean(String beanName) 判断工厂中是否蕴含给定名称的bean定义,若有则返回true
  • Object getBean(String) 返回给定名称注册的bean实例。依据bean的配置状况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该办法可能会抛出异样
  • Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
  • Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异样
  • boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
  • String[] getAliases(String name) 返回给定bean名称的所有别名
package org.springframework.beans.factory;  import org.springframework.beans.BeansException;  public interface BeanFactory {      String FACTORY_BEAN_PREFIX = "&";      Object getBean(String name) throws BeansException;      <T> T getBean(String name, Class<T> requiredType) throws BeansException;      <T> T getBean(Class<T> requiredType) throws BeansException;      Object getBean(String name, Object... args) throws BeansException;      boolean containsBean(String name);      boolean isSingleton(String name) throws NoSuchBeanDefinitionException;      boolean isPrototype(String name) throws NoSuchBeanDefinitionException;      boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;      Class<?> getType(String name) throws NoSuchBeanDefinitionException;      String[] getAliases(String name);  }

FactoryBean

个别状况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些状况下,实例化Bean过程比较复杂,如果依照传统的形式,则须要在<bean>中提供大量的配置信息。配置形式的灵活性是受限的,这时采纳编码的形式可能会失去一个简略的计划。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户能够通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的位置,Spring本身就提供了70多个FactoryBean的实现。它们暗藏了实例化一些简单Bean的细节,给下层利用带来了便当。从Spring3.0开始,FactoryBean开始反对泛型,即接口申明改为FactoryBean<T>的模式。

以Bean结尾,示意它是一个Bean,不同于一般Bean的是:它是实现了FactoryBean<T>接口的Bean,依据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean自身,如果要获取FactoryBean对象,请在id后面加一个&符号来获取

package org.springframework.beans.factory;  public interface FactoryBean<T> {      T getObject() throws Exception;      Class<?> getObjectType();      boolean isSingleton();  }

在该接口中还定义了以下3个办法:

  • T getObject():返回由FactoryBean创立的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中;
  • boolean isSingleton():返回由FactoryBean创立的Bean实例的作用域是singleton还是prototype;
  • Class<T> getObjectType():返回FactoryBean创立的Bean类型。

当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过getBean()办法返回的不是FactoryBean自身,而是FactoryBean#getObject()办法所返回的对象,相当于FactoryBean#getObject()代理了getBean()办法。
例:如果应用传统形式配置上面Car的<bean>时,Car的每个属性别离对应一个<property>元素标签。

public class Car {      private int maxSpeed ;      private String brand ;      private double price ;      //get//set 办法}

如果用FactoryBean的形式实现就灵便点,下例通过逗号宰割符的形式一次性的为Car的所有属性指定配置值:

import  org.springframework.beans.factory.FactoryBean;  public  class CarFactoryBean implements  FactoryBean<Car> {      private String carInfo ;      public  Car getObject()  throws  Exception  {          Car car = new  Car();          String[] infos = carInfo.split(",");         car.setBrand(infos[0]);        car.setMaxSpeed(Integer.valueOf(infos[1]));        car.setPrice(Double.valueOf(infos[2]));        return  car;      }      public  Class<Car> getObjectType(){          return Car.class ;      }      public boolean isSingleton(){          return false ;      }      public String getCarInfo(){          return  this.carInfo;      }        //承受逗号宰割符设置属性信息      public void setCarInfo (String carInfo){          this.carInfo = carInfo;      }  }

有了这个CarFactoryBean后,就能够在配置文件中应用上面这种自定义的配置形式配置CarBean了:

<bean d="car"class="com.dabin.spring.CarFactoryBean" P:carInfo="大奔,600,1000000"/>

当调用getBean("car")时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口办法CarFactoryBean#getObject()办法返回。如果心愿获取CarFactoryBean的实例,则须要在应用getBean(beanName)办法时在beanName前显示的加上"&"前缀:如getBean("&car");

获取bean

接下来咱们回到加载bean的阶段,当咱们显示或者隐式地调用 getBean() 时,则会触发加载 bean 阶段。如下:

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

外部调用 doGetBean() 办法,这个办法的代码比拟长,各位急躁看下:

@SuppressWarnings("unchecked")protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {    //获取 beanName,这里是一个转换动作,将 name 转换为 beanName    final String beanName = transformedBeanName(name);    Object bean;    /*     *查看缓存中的实例工程是否存在对应的实例     *为何要优先应用这段代码呢?     *因为在创立单例bean的时候会存在依赖注入的状况,而在创立依赖的时候为了防止循环依赖     *spring创立bean的准则是在不等bean创立完就会将创立bean的objectFactory提前曝光,行将其退出到缓存中,一旦下个bean创立时依赖上个bean则间接应用objectFactory               *间接从缓存中或singletonFactories中获取objectFactory     *就算没有循环依赖,只是单纯的依赖注入,如B依赖A,如果A曾经初始化实现,B进行初始化时,须要递归调用getBean获取A,这是A曾经在缓存里了,间接能够从这里取到     */    // Eagerly check singleton cache for manually registered singletons.    Object sharedInstance = getSingleton(beanName);    if (sharedInstance != null && args == null) {        if (logger.isDebugEnabled()) {            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 + "'");            }        }        //返回对应的实例,有些时候并不是间接返回实例,而是返回某些办法返回的实例        //这里波及到咱们下面讲的FactoryBean,如果此Bean是FactoryBean的实现类,如果name前缀为"&",则间接返回此实现类的bean,如果没有前缀"&",则须要调用此实现类的getObject办法,返回getObject外面真是的返回对象        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);    }    else {        //只有在单例的状况下才会解决循环依赖        if (isPrototypeCurrentlyInCreation(beanName)) {            throw new BeanCurrentlyInCreationException(beanName);        }        //尝试从parentBeanFactory中查找bean        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 {                // No args -> delegate to standard getBean method.                return parentBeanFactory.getBean(nameToLookup, requiredType);            }        }        //如果不是仅仅做类型查看,则这里须要创立bean,并做记录        if (!typeCheckOnly) {            markBeanAsCreated(beanName);        }        try {            //将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition,同时如果存在父bean的话则合并父bean的相干属性            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);            checkMergedBeanDefinition(mbd, beanName, args);            //如果存在依赖则须要递归实例化依赖的bean            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 + "'");                    }                    registerDependentBean(dep, beanName);                    try {                        getBean(dep);                    }                    catch (NoSuchBeanDefinitionException ex) {                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);                    }                }            }            // 单例模式            // 实例化依赖的bean后对bean自身进行实例化            if (mbd.isSingleton()) {                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;                    }                });                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);            }            // 原型模式            else if (mbd.isPrototype()) {                // It's a prototype -> create a new instance.                Object prototypeInstance = null;                try {                    beforePrototypeCreation(beanName);                    prototypeInstance = createBean(beanName, mbd, args);                }                finally {                    afterPrototypeCreation(beanName);                }                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);            }            // 从指定的 scope 下创立 bean            else {                String scopeName = mbd.getScope();                final 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.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;}

代码是相当长,解决逻辑也是相当简单,上面将其进行拆分解说。

获取 beanName

final String beanName = transformedBeanName(name);

这里传递的是 name,不肯定就是 beanName,可能是 aliasName,也有可能是 FactoryBean(带“&”前缀),所以这里须要调用 transformedBeanName() 办法对 name 进行一番转换,次要如下:

protected String transformedBeanName(String name) {    return canonicalName(BeanFactoryUtils.transformedBeanName(name));}// 去除 FactoryBean 的修饰符public static String transformedBeanName(String name) {    Assert.notNull(name, "'name' must not be null");    String beanName = name;    while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {        beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());    }    return beanName;}// 转换 aliasNamepublic String canonicalName(String name) {    String canonicalName = name;    // Handle aliasing...    String resolvedName;    do {        resolvedName = this.aliasMap.get(canonicalName);        if (resolvedName != null) {            canonicalName = resolvedName;        }    }    while (resolvedName != null);    return canonicalName;}

次要处理过程包含两步:

  1. 去除 FactoryBean 的修饰符。如果 name 以 “&” 为前缀,那么会去掉该 “&”,例如,name = "&studentService",则会是 name = "studentService"
  2. 取指定的 alias 所示意的最终 beanName。次要是一个循环获取 beanName 的过程,例如别名 A 指向名称为 B 的 bean 则返回 B,若 别名 A 指向别名 B,别名 B 指向名称为 C 的 bean,则返回 C。

缓存中获取单例bean

单例在Spring的同一个容器内只会被创立一次,后续再获取bean间接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从缓存中加载,而后再次尝试从singletonFactorry加载因为在创立单例bean的时候会存在依赖注入的状况,而在创立依赖的时候为了防止循环依赖,Spring创立bean的准则不等bean创立实现就会创立bean的ObjectFactory提前曝光退出到缓存中,一旦下一个bean创立时须要依赖上个bean,则间接应用ObjectFactory;就算没有循环依赖,只是单纯的依赖注入,如B依赖A,如果A曾经初始化实现,B进行初始化时,须要递归调用getBean获取A,这是A曾经在缓存里了,间接能够从这里取到。接下来咱们看下获取单例bean的办法getSingleton(beanName),进入办法体:

@Override@Nullablepublic Object getSingleton(String beanName) {    //参数true是容许晚期依赖    return getSingleton(beanName, true);}@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {    //查看缓存中是否存在实例,这里就是下面说的单纯的依赖注入,如B依赖A,如果A曾经初始化实现,B进行初始化时,须要递归调用getBean获取A,这是A曾经在缓存里了,间接能够从这里取到    Object singletonObject = this.singletonObjects.get(beanName);    //如果缓存为空且单例bean正在创立中,则锁定全局变量,为什么要判断bean在创立中呢?这里就是能够判断是否循环依赖了。    //A依赖B,B也依赖A,A实例化的时候,发现依赖B,则递归去实例化B,B发现依赖A,则递归实例化A,此时会走到原点A的实例化,第一次A的实例化还没实现,只不过把实例化的对象退出到缓存中,然而状态还是正在创立中,由此回到原点发现A正在创立中,由此能够判断是循环依赖了    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {        synchronized (this.singletonObjects) {            //如果此bean正在加载,则不解决            singletonObject = this.earlySingletonObjects.get(beanName);            if (singletonObject == null && allowEarlyReference) {                //当某些办法须要提前初始化的时候会间接调用addSingletonFactory把对应的ObjectFactory初始化策略存储在singletonFactory中                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);                if (singletonFactory != null) {                    //应用事后设定的getObject办法                    singletonObject = singletonFactory.getObject();                    记录在缓存中,留神earlySingletonObjects和singletonFactories是互斥的                    this.earlySingletonObjects.put(beanName, singletonObject);                    this.singletonFactories.remove(beanName);                }            }        }    }    return singletonObject;}

接下来咱们依据源码再来梳理下这个办法,这样更易于了解,这个办法先尝试从singletonObjects外面获取实例,如果如果获取不到再从earlySingletonObjects外面获取,如果还获取不到,再尝试从singletonFactories外面获取beanName对应的ObjectFactory,而后再调用这个ObjectFactory的getObject办法创立bean,并放到earlySingletonObjects外面去,并且从singletonFactoryes外面remove调这个ObjectFactory,而对于后续所有的内存操作都只为了循环依赖检测时候应用,即allowEarlyReference为true的时候才会应用。
这里波及到很多个存储bean的不同map,简略解释下:

1.singletonObjects:用于保留BeanName和创立bean实例之间的关系,beanName–>bean Instance

2.singletonFactories:用于保留BeanName和创立bean的工厂之间的关系,banName–>ObjectFactory

3.earlySingletonObjects:也是保留BeanName和创立bean实例之间的关系,与singletonObjects的不同之处在于,当一个单例bean被放到这外面后,那么当bean还在创立过程中,就能够通过getBean办法获取到了,其目标是用来检测循环援用。

4.registeredSingletons:用来保留以后所有已注册的bean.

从bean的实例中获取对象

获取到bean当前就要获取实例对象了,这里用到的是getObjectForBeanInstance办法。getObjectForBeanInstance是个频繁应用的办法,无论是从缓存中取得bean还是依据不同的scope策略加载bean.总之,咱们失去bean的实例后,要做的第一步就是调用这个办法来检测一下正确性,其实就是检测取得Bean是不是FactoryBean类型的bean,如果是,那么须要调用该bean对应的FactoryBean实例中的getObject()作为返回值。接下来咱们看下此办法的源码:

protected Object getObjectForBeanInstance(        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {    //如果指定的name是工厂相干的(以&结尾的)    if (BeanFactoryUtils.isFactoryDereference(name)) {        //如果是NullBean则间接返回此bean        if (beanInstance instanceof NullBean) {            return beanInstance;        }        //如果不是FactoryBean类型,则验证不通过抛出异样        if (!(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.    //如果获取的beanInstance不是FactoryBean类型,则阐明是一般的Bean,可间接返回    //如果获取的beanInstance是FactoryBean类型,然而是以(以&结尾的),也间接返回,此时返回的是FactoryBean的实例    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {        return beanInstance;    }    Object object = null;    if (mbd == null) {        object = getCachedObjectForFactoryBean(beanName);    }    if (object == null) {        // Return bean instance from factory.        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;        // Caches object obtained from FactoryBean if it is a singleton.        if (mbd == null && containsBeanDefinition(beanName)) {            mbd = getMergedLocalBeanDefinition(beanName);        }        boolean synthetic = (mbd != null && mbd.isSynthetic());        //到了这里阐明获取的beanInstance是FactoryBean类型,但没有以"&"结尾,此时就要返回factory外部getObject外面的对象了        object = getObjectFromFactoryBean(factory, beanName, !synthetic);    }    return object;}

接着咱们来看看真正的外围性能getObjectFromFactoryBean(factory, beanName, !synthetic)办法中实现的,持续跟进代码:

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {    // 为单例模式且缓存中存在    if (factory.isSingleton() && containsSingleton(beanName)) {        synchronized (getSingletonMutex()) {            // 从缓存中获取指定的 factoryBean            Object object = this.factoryBeanObjectCache.get(beanName);            if (object == null) {                // 为空,则从 FactoryBean 中获取对象                object = doGetObjectFromFactoryBean(factory, beanName);                // 从缓存中获取                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);                if (alreadyThere != null) {                    object = alreadyThere;                }                else {                    // 须要后续解决                    if (shouldPostProcess) {                        // 若该 bean 处于创立中,则返回非解决对象,而不是存储它                        if (isSingletonCurrentlyInCreation(beanName)) {                            return object;                        }                        // 前置解决                        beforeSingletonCreation(beanName);                        try {                            // 对从 FactoryBean 获取的对象进行后处理                            // 生成的对象将裸露给bean援用                            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;        }    }    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 实例对象中的外围办法之一了。这里咱们关注三个办法:beforeSingletonCreation()afterSingletonCreation()postProcessObjectFromFactoryBean()。可能有小伙伴感觉后面两个办法不是很重要,LZ 能够必定通知你,这两办法是十分重要的操作,因为他们记录着 bean 的加载状态,是检测以后 bean 是否处于创立中的要害之处,对解决 bean 循环依赖起着关键作用。before 办法用于标记以后 bean 处于创立中,after 则是移除。其实在这篇博客刚刚开始就曾经提到了 isSingletonCurrentlyInCreation() 是用于检测以后 bean 是否处于创立之中,如下:

public boolean isSingletonCurrentlyInCreation(String beanName) {    return this.singletonsCurrentlyInCreation.contains(beanName);}

是依据 singletonsCurrentlyInCreation 汇合中是否蕴含了 beanName,汇合的元素则肯定是在 beforeSingletonCreation() 中增加的,如下:

protected void beforeSingletonCreation(String beanName) {    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {        throw new BeanCurrentlyInCreationException(beanName);    }}

afterSingletonCreation() 为移除,则肯定就是对 singletonsCurrentlyInCreation 汇合 remove 了,如下:

protected void afterSingletonCreation(String beanName) {    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");    }}

咱们再来看看真正的外围办法 doGetObjectFromFactoryBean

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)        throws BeanCreationException {    Object object;    try {        if (System.getSecurityManager() != null) {            AccessControlContext acc = getAccessControlContext();            try {                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);            }            catch (PrivilegedActionException pae) {                throw pae.getException();            }        }        else {            object = factory.getObject();        }    }    catch (FactoryBeanNotInitializedException ex) {        throw new BeanCurrentlyInCreationException(beanName, ex.toString());    }    catch (Throwable ex) {        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);    }    // Do not accept a null value for a FactoryBean that's not fully    // initialized yet: Many FactoryBeans just return null then.    if (object == null) {        if (isSingletonCurrentlyInCreation(beanName)) {            throw new BeanCurrentlyInCreationException(                    beanName, "FactoryBean which is currently in creation returned null from getObject");        }        object = new NullBean();    }    return object;}

以前咱们已经介绍过FactoryBean的调用办法,如果bean申明为FactoryBean类型,则当提取bean时候提取的不是FactoryBean,而是FactoryBean中对应的getObject办法返回的bean,而doGetObjectFromFactroyBean真是实现这个性能。

而调用完doGetObjectFromFactoryBean办法后,并没有间接返回,getObjectFromFactoryBean办法中还调用了object = postProcessObjectFromFactoryBean(object, beanName);办法,在子类AbstractAutowireCapableBeanFactory,有这个办法的实现:

@Overrideprotected Object postProcessObjectFromFactoryBean(Object object, String beanName) {    return applyBeanPostProcessorsAfterInitialization(object, beanName);}@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)        throws BeansException {    Object result = existingBean;    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {        Object current = beanProcessor.postProcessAfterInitialization(result, beanName);        if (current == null) {            return result;        }        result = current;    }    return result;}

对于后处理器的应用,咱们目前还没接触,后续会有大量篇幅介绍,这里咱们只须要理解在Spring获取bean的规定中有这样一条:尽可能保障所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization办法进行解决,在理论开发过程中大能够针对此个性设计本人的业务解决。