完成对xml配置文件的解析和加载后,就可以进行bean的加载了,bean加载功能逻辑远比解析要复杂得多,spring中加载bean可以用过以下方式
AbstractApplicationContext.java
AbstractBeanFactory.java
以上这段代码相当复杂,可以看出加载和实例化bean是一个相当复杂和繁琐的过程,不过基本可以归纳为一下几个大的环节
1 缓存中获取单例bean
单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取 。若缓存中不存在,再从SingletonFactories中加载。这里需要重点说下Srping在单例下解决循环依赖的办法就是在bean创建完成之前先将bean对应的ObejctFactory提前加载进缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObejctFactory,请参照以下代码
DefaultSingletonBeanRegistry.java
首先从singletonObejcts里面尝试获取实例,如果获取不到再从earlySingletonObjects里面获取,如果还是获取不到就尝试从singletonFactories里面获取beanName对应的ObejctFactory,通过ObejctFactory的getObejct方法来创建bean,并放到earlySingletonObejects中,然后从singletonFactories中remove掉这个bean对应的objectFactory,说明一下这里面涉及到的几个map变量
- singletonObjects:用于保存beanName和创建bean实例之间的关系,beanName -> beanInstance
- singletonFactories: 用于保存beanName和对应的bean的ObejctFactory之间的关系, beanName -> ObjectFactory
- earlySingleObjects: 也是用于保存beanName和创建的bean实例时间的关系,它和singletonObjects的区别在于当bean还处于创建阶段通过earlySingleObejcts
2 从bean实例中获取对象
首先我们先来看看getObjectForBeanInstance方法,在上一节的doGetBean方法中,多次使用该方法,我们一起来看下该方法的代码
AbstractBeanFactory.java
该方法主要完成以下功能:
- 对factoryBean正确性的验证
- 对非FactoryBean类型不做任何处理
- 将GenericBeanDefinition转换成RootBeanDefinition类型
- 委托getObjectFromFactoryBean方法进行bean的解析
我们再跟踪以下getObjectFromFactory方法
FactoryBeanRegistrySupport.java
这里需要说明的是在返回object之前,spring在object = postProcessObjectFromFactoryBean(object, beanName)这行代码中做了预bean创建前的预处理。可以根据这个扩展点在bean创建前做一些针对性的自定义业务逻辑处理。后文将对此处扩展点进行详细的讲解。
FactoryBeanRegistrySupport.java