调用AbstractFactoryBean.getBean方法获取bean,实际上是调用doGetBean方法获取bean
下面进入到doGetBean所执行的操作如下:
1 、 转换bean Name
beanName可能是别名,也可能是FactoryBean ,所以需要进行一系列的解析。
(1)去除FactoryBean的修饰符,也就是如果name= "&baenName",那么会首先去除&而使name="baenName"。
(2)取指定别名所表示的最终beanName, 例如别名baenNameAlias指向名称为baenNameB的bean则返回baenNameB;
(3)若别名指向具有传递性,则需要解析出真实beanName,例如aliasA->aliasB->realBeanName。
2、缓存中获取单例bean
调用DefaultSingletonBeanRegistry.getSingleton方法从缓存中获取单例bean。单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从singletonObjects、earlySingletonObjects缓存中加载,然后再次尝试尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注人的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加人到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory。
上图中singletonFactories中是何时放入ObjectFactory的呢?查看源码可知只有DefaultSingletonBeanRegistry.
addSingletonFactory这一个方法会往singletonFactories中放入ObjectFactory。
查看addSingletonFactory方法调用链只有AbstractAutowireCapableBeanFactory.doCreateBean方法会调用DefaultSingletonBeanRegistry.addSingletonFactory。此时bean只是实例化完成处于原始状态还没有进行属性设置、初始化方法调用等,如果是单例则会提前放入singletonFactories中。单例实例化时若存在循环依赖就会获取到被依赖提前暴露的ObjectFactory。
对于单例bean获取时调用ObjectFactory.getObject()方法获取对象,其实是调用了AbstractAutowireCapableBeanFactory.
getEarlyBeanReference方法。进入getEarlyBeanReference方法,会判断不是合成的且有后处理器则会调用后处理器的getEarlyBeanReference方法。Spring是如何定义合成bean?查看AbstractBeanDefinition.setSynthetic方法上注释:设置此bean定义是否为“合成”,即应用程序本身未定义(例如,通过{@code
查看doCreateBean方法调用链只有AbstractAutowireCapableBeanFactory.createBean方法调用AbstractAutowireCapableBeanFactory.doCreateBean方法,而createBean方法会被BeanDefinitionValueResolver.
resolveInnerBean,AbstractBeanFactory.doGetBean,AbstractAutowireCapableBeanFactory.createBean调用。不管是单例bean还是prototype bean的创建在实例化之前会将当前要创建的beanName保存到DefaultSingletonBeanRegistry.
singletonsCurrentlyInCreation、AbstractBeanFactory.prototypesCurrentlyInCreation中。依赖bean创建时就可以知道被依赖bean是否正在创建中,从而可以检测到是否存在循环依赖,对于单例bean可以直接从缓存中获取到原始状态的被依赖bean,从而解决循环依赖问题。而prototype bean却不能解决循环依赖问题而是抛出异常快速失败。
3、从bean的实例中获取对象
从FactoryBean中获取bean实例委托给FactoryBeanRegistrySupport.getObjectFromFactoryBean方法完成。获取给定bean实例本身或其创建的对象(如果是FactoryBean)。其实就是用于检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该bean 对应的FactoryBean实例中的getObject()作为返回值。
如果传入的FactoryBean实例是单例的,并且要获取的beanName(其实是FactoryBean实例)已经被实例化了(单例实例化完成之后或者直接注入单例实例会放入到singletonObjects集合中,FactoryBeanRegistrySupport.containsSingleton方法从DefaultSingletonBeanRegistry.singletonObjects检查单例bean是否已经创建完成),使用DefaultSingletonBeanRegistry.
getSingletonMutex方法返回值来锁定singletonObjects这个集合。首先从缓存factoryBeanObjectCache中获取bean,如果缓存中已经有了,就直接返回该对象。如果缓存中没有,就调用doGetObjectFromFactoryBean方法来获取object,调用完成之后因为有可能在调用doGetObjectFromFactoryBean的过程中,该Bean被放到了factoryBeanObjectCache中,所以需要再次校验。如果此时发现缓存中已经有了,那就直接返回就行了,如果此时还没有就会判断一下在DefaultSingletonBeanRegistry.singletonObjects是否已经包含该实例了(其实是判断FactoryBean实例是否有效没有被销毁),如果已经包含了,我们就把这个对象存放到本地缓存(factoryBeanObjectCache)中,在存放缓存之前,会根据shouldPostProcess来决定是否对当前这个对象做进一步的操作,比如为当前这个对象应用beforeSingletonCreation,调用postProcessObjectFromFactoryBean,以及afterSingletonCreation这几个函数。在应用后处理器之前会判断当前bean是否正在创建,可能FactoryBean.getObject()方法生成的bean属性注入存在循环依赖情况。
调用FactoryBeanRegistrySupport.doGetObjectFromFactoryBean方法获取bean实例
4、prototype bean创建时检查
只有在单例情况下才会尝试解决循环依赖,如果存在beanA中有beanB的属性,beanB中有beanC的属性,beanC中有beanA的属性,那么当依赖注人的时候,就会产生当beanA还未创建完的时候因为对于beanB的创建,beanB又会对beanA的创建,再次返回创建beanA,造成循环依赖也就是情况: isPrototypeCurrentlyInCreation(beanName)判断 true直接抛出异常快速失败。
5、从parentBeanFactory获取bean
如果当前容器有父容器且在当前容器中不存在要获取bean的定义则尝试在父容器中获取指定bean