Spring IOC 容器源码分析 - 创建原始 bean 对象
1. 简介
本篇文章是上一篇文章(创建单例 bean 的过程)的延续。在上一篇文章中,我们从战略层面上领略了doCreateBean
方法的全过程。本篇文章,我们就从战术的层面上,详细分析doCreateBean
方法中的一个重要的调用,即createBeanInstance
方法。在本篇文章中,你将看到三种不同的构造 bean 对象的方式。你也会了解到构造 bean 对象的两种策略。如果你对这些内容感兴趣,那么不妨继续往下读。我会在代码进行大量的注解,相信能帮助你理解代码逻辑。好了,其他的就不多说了,进入正题吧。
2. 源码分析
2.1 创建 bean 对象的过程
本节,我们一起来来分析一下本篇文章的主角createBeanInstance
方法。按照惯例,我们还是先分析一下方法的大致脉络,然后我们再按照这个脉络去分析一些重要的调用。So. Let`s go → ↓
|
|
以上就是 createBeanInstance 方法的源码,不是很长。配合着注释,应该不是很难懂。下面我们来总结一下这个方法的执行流程,如下:
- 检测类的访问权限,若禁止访问,则抛出异常
- 若工厂方法不为空,则通过工厂方法构建 bean 对象,并返回结果
- 若构造方式已解析过,则走快捷路径构建 bean 对象,并返回结果
- 如第三步不满足,则通过组合条件决定使用哪种方式构建 bean 对象
这里有三种构造 bean 对象的方式,如下:
- 通过“工厂方法”的方式构造 bean 对象
- 通过“构造方法自动注入”的方式构造 bean 对象
- 通过“默认构造方法”的方式构造 bean 对象
下面我将会分析第2和第3种构造 bean 对象方式的实现源码。至于第1种方式,实现逻辑和第2种方式较为相似。所以就不分析了,大家有兴趣可以自己看一下。
2.2 通过构造方法自动注入的方式创建 bean 实例
本节,我将会分析构造方法自动注入的实现逻辑。代码逻辑较为复杂,需要大家耐心阅读。代码如下:
|
|
上面的方法逻辑比较复杂,做了不少事情,该方法的核心逻辑是根据参数值类型筛选合适的构造方法。解析出合适的构造方法后,剩下的工作就是构建 bean 对象了,这个工作交给了实例化策略去做。下面罗列一下这个方法的工作流程吧:
- 创建 BeanWrapperImpl 对象
- 解析构造方法参数,并算出 minNrOfArgs
- 获取构造方法列表,并排序
- 遍历排序好的构造方法列表,筛选合适的构造方法
- 获取构造方法参数列表中每个参数的名称
- 再次解析参数,此次解析会将value 属性值进行类型转换,由 String 转为合适的类型。
- 计算构造方法参数列表与参数值列表之间的类型差异量,以筛选出更为合适的构造方法
- 缓存已筛选出的构造方法以及参数值列表,若再次创建 bean 实例时,可直接使用,无需再次进行筛选
- 使用初始化策略创建 bean 对象
- 将 bean 对象放入 BeanWrapperImpl 对象中,并返回该对象
由上面的流程可以看得出,通过构造方法自动注入的方式构造 bean 对象的过程还是很复杂的。为了看懂这个流程,我进行了多次调试,算是勉强弄懂大致逻辑。由于时间有限,我并未能详细分析 autowireConstructor 方法及其所调用的一些方法,比如 resolveConstructorArguments、 autowireConstructor 等。关于这些方法,这里只写了个大概,有兴趣的朋友自己去探索吧。
2.3 通过默认构造方法创建 bean 对象
看完了上面冗长的逻辑,本节来看点轻松的吧 - 通过默认构造方法创建 bean 对象。如下:
|
|
上面就是通过默认构造方法创建 bean 对象的过程,比较简单,就不多说了。最后我们再来看看简单看看通过无参构造方法刚创建 bean 对象的代码(通过 CGLIB 创建 bean 对象的方式就不看了)是怎样的,如下:
|
|
到这里,终于看到了创建 bean 对象的代码了。在经历层层调用后,我们总算是追到了调用栈的最深处。看到这里,大家可以休息一下了,本文也差不多要结束了。好了,最后再容我多啰嗦一会,往下看。
3.写在最后
写到这里,我也算是松了一口气,终于快写完了。这篇文章写起来感觉挺不容易的,原因是 createBeanInstance 及其调用的方法是在太多了,而且很多方法逻辑还是比较复杂的,尤其是 autowireConstructor 中调用的一些方法。autowireConstructor 中调用的方法我基本上都看了一遍,但并非全部都弄懂了,有些方法只是知道个大概。所以,这篇文章写的我挺纠结的,生怕有些地方分析的不对。由于我后续还有很多东西要看,以至于我暂时没法抽出大量的时间去详细阅读 Spring 的源码。所以如果上面的分析有不对的地方,欢迎指正,我会虚心听之。如果这些不对的地方给你造成了困扰,实在很抱歉,抱歉。
好了,本篇文章先到这里。谢谢阅读!
参考
- 《Spring 源码深度解析》- 郝佳
附录:Spring 源码分析文章列表
Ⅰ. IOC
更新时间 | 标题 |
---|---|
2018-05-30 | Spring IOC 容器源码分析系列文章导读 |
2018-06-01 | Spring IOC 容器源码分析 - 获取单例 bean |
2018-06-04 | Spring IOC 容器源码分析 - 创建单例 bean 的过程 |
2018-06-06 | Spring IOC 容器源码分析 - 创建原始 bean 对象 |
2018-06-08 | Spring IOC 容器源码分析 - 循环依赖的解决办法 |
2018-06-11 | Spring IOC 容器源码分析 - 填充属性到 bean 原始对象 |
2018-06-11 | Spring IOC 容器源码分析 - 余下的初始化工作 |
Ⅱ. AOP
更新时间 | 标题 |
---|---|
2018-06-17 | Spring AOP 源码分析系列文章导读 |
2018-06-20 | Spring AOP 源码分析 - 筛选合适的通知器 |
2018-06-20 | Spring AOP 源码分析 - 创建代理对象 |
2018-06-22 | Spring AOP 源码分析 - 拦截器链的执行过程 |
Ⅲ. MVC
更新时间 | 标题 |
---|---|
2018-06-29 | Spring MVC 原理探秘 - 一个请求的旅行过程 |
2018-06-30 | Spring MVC 原理探秘 - 容器的创建过程 |
- 本文链接: https://www.tianxiaobo.com/2018/06/06/Spring-IOC-容器源码分析-创建原始-bean-对象/
from: http://www.tianxiaobo.com/2018/06/06/Spring-IOC-%E5%AE%B9%E5%99%A8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E5%88%9B%E5%BB%BA%E5%8E%9F%E5%A7%8B-bean-%E5%AF%B9%E8%B1%A1/
Spring IOC 容器源码分析 - 创建原始 bean 对象相关推荐
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...
- Spring IOC 容器源码分析 - 填充属性到 bean 原始对象
1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...
- Spring IOC 容器源码分析系列文章导读
1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...
- Spring IOC 容器源码分析 - 余下的初始化工作
1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...
- Spring IOC 容器源码分析 - 循环依赖的解决办法
1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...
- Spring IOC 容器源码分析 - 获取单例 bean
1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...
- Spring IOC 容器源码分析系列文章导读 1
1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...
- Spring IOC 容器源码分析
Spring IOC 容器源码分析 创建时间: 2017-11-15 00:00:00 [TOC] Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring ...
- 模拟spring IOC、源码分析
springIOC what is IOC 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做 ...
最新文章
- python正则取字符串日期_python 正则表达式获取字符串中所有的日期和时间
- UI培训分享:如何提升自己的UI设计能力
- 5菜鸟教程_XPLANE10菜鸟基础教程系列 飞机、机场以及天气的设置
- 玩转Linux:常用命令实例指南
- 10G DB_LINK的问题
- dr. unarchiver_P160 四季可穿,数仙女尽折腰!醉高版本Dr马丁靴女2020秋冬新款牛筋底1460英伦风8孔系带复古机车军靴真皮短靴马丁靴...
- 原创:MS Dynamics AX - XBRL 功能
- LINQ之路 2:C# 3.0的语言功能(上)
- Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证以及无痛刷新访问令牌
- java厨房_JAVA环境搭建,厨房安装图文教程!
- 【ACM】N皇后问题
- 线程池(领导者-追随者,生产者-消费者等)小结
- CentOS安装EPEL源
- Excel·VBA数组组合函数、组合求和
- 三菱PLC 计数器C
- 试试Live Witer
- 《JAVA 技术》第二次作业
- HDU 6080 度度熊保护村庄 (叉积判断点线关系+图论)
- 长城汽车召回上万辆欧拉IQ:电池存在安全隐患,曾因自燃被拉黑
- 22万抢注“活动”双拼域名,95后创业者却因困意失之交臂