天天看点

Spirng源码分析总结——Bean

该文章基于《Spring源码深度解析》撰写,感谢郝佳老师的奉献

如果想要弄清Bean创建到使用的一整套流程实际上非常复杂,bean的处理可以是Spring的核心之一:

  1. 首先需要对标签属性进行处理
  2. 进行Bean的加载
  3. 进行BeanFactory的加载

下面按顺序进行介绍对标签属性的处理,这一部分的的处理很复杂(以后用空再慢慢补充,现在仅给出逻辑步骤):

  1. 首先委托BeanDefinitionDelegate类的parseBeanDefinationElement方法对元素进行解析,返回BenaDefinitionHolder类型的实例,此时该实例已经具有了配置文件中的各种属性
  2. 如果默认标签还有自定义属性,还需要对自定义属性进行解析
  3. 上面2步就已经完成了解析,接下来的注册操作委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法
  4. 最后发出响应事件,通知监听器,告知该bean的标签已经解析完成

就下来介绍bean的加载,该部分更加复杂,以后有机会再介绍具体细节,以后用空再慢慢补充,现在仅给出逻辑步骤):

  1. 转换对应beanName(实际上就是消除别名依赖)
  2. 尝试从缓存中加载单例(使用了双锁检查(DCL))
  3. bean的实例化(在Sping中一般通过反射机制实例化bean,如果存在缓存,那么直接返回缓存,否则依赖于ObjectFactory进行创建(同时可以处理处理循环依赖的问题),并且在创建时调用实例化前、后的后处理器,同时进行动态AOP织入,属性的注入,在前面的事情都完成之后Spring将通过init-method对bean进行自定义初始化方法调用,并且将BeanDefinition转换为BeanWrapper返回)
  4. 原型模式(prototype)的依赖检查(原型模式无法处理循环依赖,因为Spring不会缓存prototype作用域的bean,所以也无法提前曝光ObjectFactory)
  5. 检测parentFactory
  6. 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
  7. 寻找依赖
  8. 针对不同的scope进行bean的创建(默认singleton,prototype,reqeuest)
  9. 类型转换

    因为这东西确实不好讲,我直接给一张我整理的图:

    Spirng源码分析总结——Bean

    下面主要解释一下Spring中如何处理循环依赖,分为三种情况:

    构造器循环依赖:抛出异常

    setter循环依赖:通过提前暴露的ObjectFactory进行创建

    prototype的循环依赖:直接报错

继续阅读