Bean的加载
- 转换对应的BeanName
这里传入的参数可能是别名,也可能是FactoryBean所以需要一系列的解析- 去除FactoryBean的修饰符,也就是如果name=“&aa”,那么会首先去除&
- 取指定alias所表示的最终beanName
- 查实从缓存中加载实例
单例在Spring的同一个容器内只会创建一次,后续获取Bean就直接从单例缓存中获取。 - bean的实例化
如果从缓存中获取到的bean的原始形态,则需要对bean进行实例化。 - 原型模式的依赖检查
只有在单例情况下才会查实解决循环以来,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖。 - 检测parentBeanFactory
- 将存储XML配置文件的GernericBeanDefinition转换成RootBeanDefinition
- 寻找依赖
- 针对不同的scope进行bean的创刊
- 类型转换
FactoryBean
FactoryBean主要完成的任务是对接口定制实例化bean,支持范型。
- T getObject()返回FactoryBean创建的bean实例
- boolean isSingleton()返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。
- Class getObjectType() 返回FactoryBean创建的bean类型。
缓存中获取单例bean
重点解决循环依赖,因为Bean加载是单例的,会现在缓存中加载,然后再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建以来的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建的bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上一个bean,则直接使用ObjectFactory。
从bean的实例中获取对象
在getBean方法中,getObjectForBeanInstance是个高频的使用方法。他主要是检测当前bean是否时一个FactoryBean如果是要调用getObjectFactory()获取指定的bean。
- 对FactoryBean正确性的验证
- 对非FactoryBean不做任何处理
- 对bean进行转换
- 将从Factory中解析bean的工作委托给getObjectFromFactoryBean
获取单例
获取bean实例会现在缓存中获取实例,如果获取不到那么就需要重新进行bean加载的过程了,而Spring中使用getSingleton的重载方法实现bean的加载过程。
- 检查缓存是否已经加载过
- 若没有加载,则记录beanName的正在加载状态
- 加载单例前记录加载状态
- 通过调用参数传入的ObjectFactory的个体Object方法实例化bean
- 加载单例后的处理方法调用
- 将结果记录至缓存并删除bean过程中所记录的各种辅助状态
- 返回处理结果
准备创建Bean
- 根据设置的class属性或者格局className来解析class
- 对override属性进行标记及验证
- 应用初始化前的后处理器,解析指定bean时候存在初始化前的短路操作
- 创建bean
循环依赖
Spring如何解决循环依赖
Spring容器循环依赖包括构造器循环依赖和setter循环依赖。
Spring把循环依赖分为了三类
- 构造器循环依赖
表示通过构造器注入构成的循环依赖,此依赖时无法解决的,只能跑出异常来提示。 - setter循环依赖
对于setter注入造成的循环以来时通过Spring容器提前暴露的ObjectFactory来处理的。 - prototype范围的循环依赖,Spring无法完成依赖注入,所以无法提前暴露一个,但是可以通过setAllowCircularReferences(false)来禁止循环引用。
创建Bean
- 如果是单例则需要首先清楚缓存
- 实例化bean,将BeanDefinition转换成BeanWrapper
- 如果存在工厂方法则使用工厂方法初始化。
- 一个类有多个构造行数,每个构造函数都有不同的参数,所以需要更具参数锁定构造函数并进行初始化。
- 如果既不存在工厂方法也不存在带有参数的构造函数,则默认调用默认的构造函数进行bean的实例化。
- MergedBeanDefinitionPostProcessor的应用
- 依赖处理
- 属性填充
- 循环依赖检查
- 之前说过Spring中解决循环依赖只对单例有效,对于prototype的bean是没有好的解决办法,这里只是判断是否有循环依赖,并判断是否需要抛出异常。
- 注册DisposableBean
- 完成创建兵器返回