Bean的加载所涉及到的大致步骤:

1)转换对应beanName

为什么需要转换beanName呢?因为传入的参数可能是别名,也可能是FactoryBean,所以需要一系列的解析,这些解析内容包括如下

去除FactoryBean的修饰符,也就是如果name="&aa",name会首先去除&而使name="aa"

取指定alias所表示的最终beanName,例如别名A指向名称为B的bean则返回B;若别名A指向别名B,别名C又指向名称为C的bean则返回C。

2)尝试从缓存中加载实例

单例在Spring的同一个容器中只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。当然这里也只是尝试加载,首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载,因为在创建单例bean的时候会存在依赖注入的情况。而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直接使用ObjectFactory。

3)bean的实例化

如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean,。例如win需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初识状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。

4)原型模式的依赖检查

只有在单例情况下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A额的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就情况isPrototypeCurrentlyInCreation(beanName)判断为true

5)检测parentBeanFactory

如果缓存没有数据的话直接转到父类工厂上去加载了,这是为什么呢?

前提条件是:parentBeanFactory!=null&&!containsBeanDefinition(beanName),parentBeanFactory!=null。parentBeanFactory如果为空,则其他一切都是浮云。最重要的是!containsBeanDefinition(beanName),它是在检测如果当前加载的XML配置文件中不包含beanName所对应的配置就只能到parentBeanFactory去尝试下,然后再去递归调用getBean方法

6)将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition

因为从XML配置文件中读取到的Bean信息存储在GernericBeanDefinition中的,但是所有的Bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。

7)寻找依赖

因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要先加载依赖的bean,所以在spring加载顺序中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖

8)针对不同的scope进行bean的创建

9)类型转换

【Spring源码深度解析学习系列】Bean的加载(六)的更多相关文章

  1. 【Spring源码深度解析学习系列】容器的基础XmlBeanFactory(二)

    一.配置文件封装 Spring的配置文件读取是通过ClassPathResource进行封装的,如new ClassPathResource("test.xml"),那么Class ...

  2. 【Spring源码深度解析学习系列】核心类介绍(一)

    一.DefaultListableBeanFactory 首先看一下结构 由图可知XmlBeanFactory继承自DefaultListableBeanFactory,而DefaultListabl ...

  3. 【Spring源码深度解析学习系列】复杂标签属性解析(四)

    一.创建用于属性承载的BeanDefinition BeanDefiniton是一个接口,在Spring中存在三种实现:RootBeanDefinition.ChildBeanDefinition.G ...

  4. 【Spring源码深度解析学习系列】默认标签解析(三)

    Spring的标签包括默认标签和自定义标签两种 默认标签的解析方法: ###DefaultBeanDefinitionDocumentReader.java### private void parse ...

  5. 【Spring源码深度解析学习系列】注册解析的BeanDefinition(五)

    对于配置文件,解析和装饰完成之后,对于得到的beanDefinition已经可以满足后续的使用要求了,还剩下注册,也就是processBeanDefinition函数中的BeanDefinitionR ...

  6. Spring源码分析(十一)bean的加载

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 经过前面的分析,我们终于结束了对XML配置文件的解析,接下来将会面临更大 ...

  7. spring源码深度解析— IOC 之 bean 创建

    在 Spring 中存在着不同的 scope,默认是 singleton ,还有 prototype.request 等等其他的 scope,他们的初始化步骤是怎样的呢?这个答案在这篇博客中给出. s ...

  8. spring源码深度解析— IOC 之 bean 的初始化

    一个 bean 经历了 createBeanInstance() 被创建出来,然后又经过一番属性注入,依赖处理,历经千辛万苦,千锤百炼,终于有点儿 bean 实例的样子,能堪大任了,只需要经历最后一步 ...

  9. spring源码深度解析— IOC 之 开启 bean 的加载

    概述 前面我们已经分析了spring对于xml配置文件的解析,将分析的信息组装成 BeanDefinition,并将其保存注册到相应的 BeanDefinitionRegistry 中.至此,Spri ...

随机推荐

  1. Erlang编程语言的一些痛点

    Erlang编程语言的一些痛点 http://www.zhihu.com/question/34500981

  2. hadoop hdfs 命令

    hdfs命令常用操作: hdfs帮助 -help [cmd] 显示命令的帮助信息 [hadoop@hadoop-01 ~]$ hdfs dfs -help ls 递归显示当前目录下的所有文件: [ha ...

  3. IDEA VS 快捷键 大全

    [参考]IntelliJ IDEA 常用 黄金 快捷键  总结 不断更新     一.VS常用快捷键 (01).快速插入foreach.try等循环:Tab + Tab; (02).回到光标前一位置: ...

  4. MySQL时间戳时间

    MySQL中: now():获取当前时间:例:SELECT now(); unix_timestamp():将时间转换为时间戳:例: SELECT unix_timestamp(now());

  5. pi4j,Netbeans中togglebutton跟Jbutton的区别

    一组togglebutton中会始终有一个是按下去的状态 一组commandbutton就全部都始终都是弹起的状态

  6. CentOS7 防火墙配置(关闭)

    CentOS7 的防火墙配置跟曾经版本号有非常大差别,经过大量尝试,最终找到解决这个问题的关键 CentOS7这个版本号的防火墙默认使用的是firewall.与之前的版本号使用iptables不一样. ...

  7. 腾讯游戏设计(tgideas.qq.com)回复处CSRF任意换马甲

    http://tgideas.qq.com GET /cgi-bin/comments/sendreply.cgi?iActivId=1&iSubActivId=215722&iPar ...

  8. 【玩转Golang】 自定义json序列化对象时,非法字符错误原因

    由于前台web页面传来的日期对象是这样的格式“2010-11-03 15:23:22”,所以我安装网上查来的办法,自定义包装了time.Time对象,实现自己的Marshal和UnMarshal方法 ...

  9. thinkphp 外部js语言包

    Thinkphp php文件也外部js文件公用同一个语言包 一 . php语言包转json数据格式 1.新建验证字段的语言包 application\common\lang\validate-cn.p ...

  10. Global.asax的Application_BeginRequest实现url重写无后缀的代码

    本文为大家详细介绍下利用Global.asax的Application_BeginRequest 实现url重写其无后缀,具体核心代码如下,有需求的朋友可以参考下,希望对大家有所帮助 利用Global ...