Spring源码阅读目录
第一部分——IOC篇
第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如让你来写IOC容器——加载资源篇
第三章 Spring之假如让你来写IOC容器——解析配置文件篇
第四章 Spring之假如让你来写IOC容器——XML配置文件篇
第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如让你来写IOC容器——Scope和属性填充
第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式
第八章 Spring之假如让你来写IOC容器——拓展篇
第九章 Spring之源码阅读——环境搭建篇
第十章 Spring之源码阅读——IOC篇
第二部分——AOP篇
第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的内容——概念篇
第十三章 Spring之假如让你来写AOP——AOP联盟篇
第十四章 Spring之假如让你来写AOP——雏形篇
第十五章 Spring之假如让你来写AOP——Joinpoint(连接点)篇
第十六章 Spring之假如让你来写AOP——Pointcut(切点)篇
第十七章 Spring之假如让你来写AOP——Advice(通知)上篇
第十八章 Spring之假如让你来写AOP——Advice(通知)下篇
第十九章 Spring之假如让你来写AOP——番外篇:Spring早期设计
第二十章 Spring之假如让你来写AOP——Aspect(切面)篇
第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇
第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
第二十三章 Spring之假如让你来写AOP——融入IOC容器篇
第二十四章 Spring之源码阅读——AOP篇
第三部分——事务篇
第二十五章 Spring之曾经的老朋友——事务
第二十六章 Spring之假如让你来写事务——初稿篇
第二十七章 Spring之假如让你来写事务——铁三角篇
第二十八章 Spring之假如让你来写事务——属性篇
第二十九章 Spring之假如让你来写事务——状态篇
第三十章 Spring之假如让你来写事务——管理篇
第三十一章 Spring之假如让你来写事务——融入IOC容器篇
第三十二章 Spring之源码阅读——事务篇
第四部分——MVC篇
第三十三章 Spring之梦开始的地方——MVC
第三十四章 Spring之假如让你来写MVC——草图篇
第三十五章 Spring之假如让你来写MVC——映射器篇
第三十六章 Spring之假如让你来写MVC——拦截器篇
第三十七章 Spring之假如让你来写MVC——控制器篇
第三十八章 Spring之假如让你来写MVC——适配器篇
第三十九章 Spring之假如让你来写MVC——番外篇:类型转换
第四十章 Spring之假如让你来写MVC——ModelAndView篇
第四十一章 Spring之假如让你来写MVC——番外篇:数据绑定
第四十二章 Spring之假如让你来写MVC——视图篇
第四十三章 Spring之假如让你来写MVC——上传文件篇
第四十四章 Spring之假如让你来写MVC——异常处理器篇
第四十五章 Spring之假如让你来写MVC——国际化篇
第四十六章 Spring之假如让你来写MVC——主题解析器篇
第四十七章 Spring之假如让你来写MVC——闪存管理器篇
第四十八章 Spring之假如让你来写MVC——请求映射视图篇
第四十九章 Spring之假如让你来写MVC——番外篇:属性操作
第五十章 Spring之假如让你来写MVC——融入IOC容器篇
第五十一章 Spring之源码阅读——MVC篇
第五部分——Boot篇
第五十二章 Spring之再进一步——Boot
第五十三章 Spring之假如让你来写Boot——环境篇
第五十四章 Spring之假如让你来写Boot——注解篇(上)
第五十五章 Spring之假如让你来写Boot——注解篇(下)
第五十六章 Spring之假如让你来写Boot——SPI篇
第五十七章 Spring之假如让你来写Boot——配置文件篇(上)
第五十八章 Spring之假如让你来写Boot——配置文件篇(下)
第五十九章 Spring之假如让你来写Boot——番外篇:再谈Bean定义
第六十章 Spring之假如让你来写Boot——自动装配篇
第六十一章 Spring之假如让你来写Boot——番外篇:杂谈Starter
第六十二章 Spring之假如让你来写Boot——番外篇:重构BeanFactory
第六十三章 Spring之假如让你来写Boot——番外篇:再谈ApplicationContext
第六十四章 Spring之假如让你来写Boot——内嵌Web容器篇
第六十五章 Spring之假如让你来写Boot——Main方法启动篇
第六十六章 Spring之最终章——结语篇
文章目录
前言
对于Spring一直都是既熟悉又陌生,说对它熟悉吧,平时用用没啥问题,但面试的时候被问的一脸懵逼,就很尴尬,都不好意思在简历上写着熟悉Spring了
所以决定花点时间研究研究Spring的源码。主要参考的书籍是:《Spring源码深度解析(第2版)》、《Spring揭秘》、《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》
书接上回,在上篇 第六十章 Spring之假如让你来写Boot——自动装配篇 中,A君 昨天已经完成了自动装配这一大功能,自动装配可以说是 Boot 的半壁江山,剩下的东西也不多了。。。
尝试动手写IOC容器
出场人物:A君(苦逼的开发)、老大(项目经理)
背景:老大 要求 A君在一周内开发个简单的 IOC容器
前情提要:A君 已经完成了自动装配这一大功能。。。
杂谈Starter
前面 A君 长篇大论解释了自动装配机制,不过呢,除了 SPI 机制之外,还有大名鼎鼎Starter
,这个大家都耳熟能详的东西。接下来,A君 就以国内大名鼎鼎的Druid
连接池为例,详细了解下剩余的内容吧
什么是BOM?
不知道大家在平时开发中有没有遇到这样子的问题:
场景一:模块A需要添加个功能,这个由 A君 进行开发,经过一阵分析后,A君 决定引入c-1.0.jar
。模块B也需要添加一个功能,由 B君 开发,B君 分析后,决定引入c-2.0.jar
。这时候Maven
就开始懵逼了,Maven
表示很无奈,它只是个编译工具,也不知道到底以哪个版本为主,只能是先找到哪个就用哪个了
场景二:A君 打算新建一个项目,这时候需要引入大量的jar
包,分别引入了a-1.0.jar
、b-2.0.jar
。看着很正常吧,不过呢?假如a-1.0.jar
也依赖b.jar
,只是版本是1.0
。嘿嘿,这时候就跟场景一的问题一模一样了
如果是场景一,大不了在群里大吼一声:到底是谁干的?场景二可没这么简单了,第三方jar
包引起的版本问题更为隐蔽。Maven
更无法自己解决了,工具解决不了,那问题就得落到人身上了,这时候开发也很难受,要知道因为jar
包版本不统一引起的问题是没有道理可讲的,还经常折腾半天,解决了也没有任何成就感,简直就是开发中的‘毒瘤’。
既然存在问题,那就得想办法解决问题。现在jar
版本问题搞得大家都难受,Maven
就提出了一个解决方案——版本控制,也就是所谓的BOM
。复杂的概念在这里就不说了,A君 也不知道。还是一样的问题:如果让你来解决,你会怎么做?也好办,既然问题是由于不同人引入不同版本导致的,那就在一个地方统一导入就行了。在现在的开发中,每个项目一般都会有个父工程。父工程的pom.xml
文件大体如下:
解决jar
版本问题的奥秘就在dependencyManagement
标签下。dependencyManagement
下边规定了各个jar
包的版本,它只定义了依赖的版本,不会自动引入这些依赖。子模块需要的话,直接根据groupId
和artifactId
引入就行了,不再需要带上版本,这样就能解决版本问题了。像这种专门用于管理jar
包版本的就称作是BOM
了。当然了,如果子模块还是需要使用不同于BOM
中管理的版本时,依然可以在模块中显式指定版本号,从而覆盖BOM
中的配置
啊,BOM
虽然好,可是还是需要开发花大量的在版本管理上,而且还得知道各个jar
包之间的依赖关系,这也太为难人了。那有没有办法让开发尽量少接触这些玩意。是的,又是那个男人站出来了。Spring 显然也考虑到了这点,所以它将大部分公共的jar
包进行管理,起码和 Spring 版本是一一对应的,不会存在版本问题
如何定义一个Starter?
引入依赖
了解完BOM
之后,再来看spring-boot-starter
就很明了了。A君 打开druid-spring-boot-starter.jar
中的pom.xml
。如下:
注意看,这个dependency
很特殊哦,它的type
不同于平时常见jar
,而是pom
类型。类型不一样,工作方式自然也就不同了。显然,这里是把 SpringBoot 的整个BOM
导入进来了。除了这种方式外,还一种方式是继承,也就是parent
标签:
这两种方式各有优缺点,大致如下:
parent
:侧重于提供项目全局的配置和统一设置(包含依赖管理、插件、构建设置等),以单一继承方式传递给所有子模块
BOM
:专门用于管理依赖版本,通过导入的方式将多个BOM
的版本规则“组合”到项目中,解决了单继承带来的限制,同时仅用于版本控制,不影响其他构建配置。
parent
的职能范围要大于BOM
,在工作中,还是根据实际需要进行选择,没有最好只有最合适的
自动装配
导入弄清楚之后,接着 A君 就直奔spring.factories
文件,这里是 SPI 的入口,必然指定了某个配置类。如下:
果然不出所料,这里指向了DruidDataSourceAutoConfigure
,那就继续跟下去看看吧。代码如下:
看到这里,A君 心里了然,都是老熟人了,全是之前了解过的东西了
为何IDEA中会有提示?
自动装配和版本管理,到这里 A君 就彻底明白。不过,还有个小问题,A君 有点好奇,就是平时在配置yaml
文件的时候,会自动提示属性或者值,这又是怎么做到的?Spring 和 IDEA 之间,到底存在着什么py交易
为了满足自己的好奇心,A君 又跑去druid-spring-boot-starter.jar
底下翻找了起来。不出所料,在源码包里发现了一个奇怪的家伙
其他文件都好说,唯独这个json
文件,新面孔。抱着试一试的心态,A君 打开了他:
这就不奇怪了呀,明显是properties
定义各个属性,并且用group
进行分组。而hits
则定义了properties
的值
项目没用到的自动装配怎么办?
基于方便用户使用的角度,SpringBoot 尽量集成了市面上很多通用的框架,这也导致一个问题:在一个项目中,往往并不会用到那么多组件,这时候把这么多东西全部加载到内存,显然是不合适的,到时怕是32G内存都不够用了。所以为了我们的用户大大不骂娘,SpringBoot 同志还需多多努力才行。
到此为止,整个自动装配的逻辑 A君 都弄明白了,再无秘密可言
总结
正所谓树欲静而风不止,欲知后事如何,请看下回分解(✪ω✪)