Spring源码阅读笔记01:源码阅读环境准备
1. 写在前面
对于做Java开发的同学来说,Spring就像是一条绕不过去的路,但是大多数也只是停留在对Spring的简单使用层面上,对于其背后的原理所知不多也不愿深究,关于这个问题,我在平时的生活及工作中也在不断思考。
为什么要阅读Spring的源码?
- 不是为了读源码而读源码,Spring有很好的设计思想,值得学习;
- Spring是当前使用最广泛的一个开发框架,学习其原理可以帮助我们更好的应对工作中出现的各种框架相关的问题;
- 在开发中越来越多的使用到了各种各样的框架,渐渐的开发人员只会引入jar包进行开发了,对于一些应用底层的问题难以快速解决,阅读源码可以让我们站在一个更高的视角看待我们的开发的工程,对整个系统也能够有更深入的了解,有助于增加自己的深度;
- Spring对很多其它的框架(比如mybatis、springmvc等)提供了很好的集成,学习Spring的原理可以更好的帮助我们理解其他的框架的工作原理,从而对整个系统能够有更深入的了解;
以上只是个人观点,基于此,打算阅读一下Spring源码并将相关读书笔记总结成文,以供后面回顾。所谓磨刀不误砍柴功,要阅读源码,首先我们要有一个源码阅读的环境,所以第一篇文章先来总结一下源码阅读环境的搭建。
2. 构件源码阅读环境
首先声明一些基本配置:这个读书笔记系列中涉及到的开发工具是eclipse,Spring版本为3.2.18.RELEASE,电脑所使用的操作系统为win 10。
阅读Spring源码常用的方式有两种:
- 新建一个工程,引入Spring的jar包,然后直接阅读;
- 下载Spring官方源码并导入到工程中,然后进行阅读;
前者非常便捷,后者逼格更高,而且可以修改源码,两者没有好坏之分,使用哪种从心即可,这里只是记录一下在搭建源码阅读环境的过程中所踩过的坑。
2.1 引入jar包
采用这种方式非常方便,只需要在项目中引入Spring相关的依赖,再简单配置一下,就能阅读源码了。笔者在阅读时是通过maven进行构建工程的,所使用的Spring依赖如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.18.RELEASE</version>
</dependency>
这种方式比较简单,对于想阅读Spring源码的同学来说,其简单使用及配置自然是会的,在此就不过多论述这部分了。
2.2 下载官方源码并导入工程
这种方式在我看来就是逼格比较高罢了(可以修改Spring的源码),但是环境的搭建还是要费一番功夫的,笔者当初在这个地方还是费了一些时间的,特在此记录当时踩过的坑,废话有点多,这就开始吧。
Spring的源码是托管在github上,所以我们先需要上网把它下下来。首先输入网址https://github.com/,搜索Spring,本次导入的源码版本为3.2.x,进行排序按照stars多少来选择():
选择版本:
点击下载zip文件:
下载下来后,解压缩得到源码文件:
此时,对应文件夹下已经存在相应的源码了,但是这个源码并不能直接导入Eclipse中,我们还需要将源码转换为Eclipse可以读取的形式。因为源码下面有很多工程,这里建议只对我们感兴趣的工程进行Eclipse工程转换,比如我们想要查看Spring容器部分源码,打开cmd命令窗口,将当前目录切换至源码所在目录,这里是Spring-Context文件夹下,执行命令"gradle cleanidea eclipse"(前提得是要安装了gradle才行,因为Spring的源码是用gradle构建的),当窗口出现如下状态说明已经成功了:
如果提示下面的错误:
Could not get unknown property 'classesDir' for main classes of type org.gradle.api.internal.tasks.DefaultSourceSetOutput
The classesDir property was deprecated in gradle 4.x, and removed in gradle 5.x (see the release notes).
这是由于gradle的版本过高导致,需要切换到4以下,详见 Could not get unknow property 'classesDir' for main classes ...
如果出现如下错误:
Could not find matching constructor for: org.gradle.plugins.ide.eclipse.model.ProjectDependency(org.codehaus.groovy.runtime.GStringImpl,java.long.String)
这也是由于gradle的版本导致,对于的源码中缺少构造器,详见:如何从github上拉取Spring-framwork源码项目,导入到eclipse中。
解决如上问题之后,这时,我们再看对应的文件夹会发现,已经出现了作为Eclipse工程所必须的.project与.classpath文件了,这时就可以打开Eclipse,将工程导入了,导入项目之后相关依赖的项目也需要导入。
导入之后,项目上有个红叹号,右键项目--properties--Java Build Path--Libraries,发现是丢失spring-asm-repack和spring-cglib-repack包,安照下面的步骤来处理:
- 到这个网站下载spring的lib压缩包,我下载的是和源码对应的spring-framework-3.2.18.RELEASE-dist.zip;
- 解压spring-framework-3.2.18.RELEASE-dist.zip 在spring-framework-3.2.18.RELEASE-dist\spring-framework-3.2.18.RELEASE\libs路径下找到spring-core-3.2.18.RELEASE.jar;
- 再把spring-core-3.2.18.RELEASE.jar用压缩工具解压出来;
- 然后cmd到这个目录下执行如下两条命令:
jar cvf spring-cglib-repack-3.1.jar org\springframework\cglib
jar cvf spring-asm-repack-5.0.4.jar org\springframework\asm
命令执行成功后会生成如下jar包:
将这两个jar包导入项目之后,错误就消除了:
这里我们已经导入core,同样的操作,我们导入spring-beans,这里就已经具备基本的IoC功能了,我们可以写点测试代码试试。
beans.xml,配置文件需要放在core项目下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="testBean" class="test.TestBean">
<property name="name" value="hello"></property>
</bean>
</beans>
下面是测试用例:
public class Test {
public static void main(String[] args) {
/**
* 用XmlBeanFactory这个方式获得bean,现在已经不用这个方式了
*/
XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
TestBean myTestBean = (TestBean) xmlBeanFactory.getBean("myTestBean");
System.out.println( myTestBean+ "---"+ myTestBean.getName());
}
} public class TestBean {
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
运行结果:
好啦,如果顺利执行到这一步,那就代表你成功了,接下来你就能对Spring为所欲为了。。
3. 遇到问题
除了上面遇到的问题,还有几个问题记录在这里。
导入spring-context时候遇到问题:Access restriction: The type 'Application' is not API (restriction on required library rt.jar)。
解决办法:右键spring-context工程--properties--Libraries--点开JRE--Access Rules--Edit--Add--添加新规则com/sun/net/**,详见参考文献4,参考如下:
我们瞥一眼beans工程中的代码:
4. 参考文献
1. eclipse导入spring源码二(丢失的spring-asm-repack和spring-cglib-repack)
2. Spring源码下载及安装
3. Build path entry is missing” error when trying to create a new project in Eclipse
4. Access restriction: The type 'Application' is not API (restriction on required library rt.jar)
Spring源码阅读笔记01:源码阅读环境准备的更多相关文章
- uml大战需求分析阅读笔记01
<<UML大战需求分析>>阅读笔记(1) 刚读了uml大战需求分析的第一二章,读了这些内容之后,令我深有感触.以前学习uml这门课的时候,并没有好好学,那时我认为这门课并没有什 ...
- Qt Creator 源码学习笔记01,初识QTC
阅读本文大概需要 4 分钟 Qt Creator 是一款开源的轻量级 IDE,整个架构代码全部使用 C++/Qt 开发而成,非常适合用来学习C++和Qt 知识,这也是我们更加深入学习Qt最好的方式,学 ...
- Cognitive Graph for Multi-Hop Reading Comprehension at Scale(ACL2019) 阅读笔记与源码解析
论文地址为:Cognitive Graph for Multi-Hop Reading Comprehension at Scale github地址:CogQA 背景 假设你手边有一个维基百科的搜索 ...
- 一行一行分析JQ源码学习笔记-01
jQuery (function(window,undefined){ }) undefined 防止外部参数中 var undefined =10:以此来改变内部 undefined 不太建议用严 ...
- Vue2.x源码学习笔记-Vue源码调试
如果我们不用单文件组件开发,一般直接<script src="dist/vue.js">引入开发版vue.js这种情况下debug也是很方便的,只不过vue.js文件代 ...
- <精通JavaScript>---阅读笔记01
下面是阅读精通JavaScript书做的相关笔记. JS中的函数重载 函数重载必须依赖两件事情:判断传入参数数量的能力和判断传入参数类型的能力,在js中每个函数都带有一个仅在这个函数范围内作用的变量, ...
- UML大战需求分析--阅读笔记01
本次阅读的书籍是<UML大战需求分析>,看了前两章的内容:1 大话UML,2绞尽脑汁的需求分析.这两章内容关联不大,分开描述. 第一章:大话UML 本章主要概述UML是什么,有什么内容.U ...
- 《UML大战需求分析》阅读笔记01
在刚学习软件开发的课程时,首先学习了UML设计,但只是学习了基本的语法,虽然在学期通过课堂练习进行了实践,但并没有真正理解其中作用.为了进一步的理解UML的用法,我阅读了<UML大战需求分析&g ...
- 《java与模式》阅读笔记01
这次我读了前两章的内容,就如书名所言,这本书主要将的就是java中的模式,在书中的序言就把所有的模式都介绍了一下,主要有, 1.创建模式:简单工厂模式,工厂方法模式,抽象工厂模式,建造模式 2.行为模 ...
随机推荐
- 最近发现Git的速度好慢
最近发现Git速度好慢,Git Bash要等5秒左右才能操作,网上查了查原因,说是火绒的问题,哎平时也用不到,看日志一个毒都没光顾过我电脑,火绒卸载! 卸了后果然快多了
- SpringBoot + Apache Shiro权限管理
之前配置过Spring + SpringMVC + JPA + Shiro后台权限管理 + VUE前台登录页面的框架,手动配置各种.xml,比较繁琐,前几天写了个SpringBootShiro的Dem ...
- 安全检测检查清单(Web)网站
(一) 检查项:弱锁定机制 优先级:高 检查要点:检查系统帐号锁定机制健壮性 检查方法: 1.尝试使用错误的密码登录5次,查看账户是否被锁定2.等待10分钟再次测试,确认该用户是否还处于锁定状态 (二 ...
- 【Java并发基础】加锁机制解决原子性问题
前言 原子性指一个或多个操作在CPU执行的过程不被中断的特性.前面提到原子性问题产生的源头是线程切换,而线程切换依赖于CPU中断.于是得出,禁用CPU中断就可以禁止线程切换从而解决原子性问题.但是这种 ...
- java 方法定义 调用
一.定义 格式: 修饰符 返回值类型 方法名(参数){ return } 相比之下python方法的定义简单多了 public static 是修饰符 二.调用 方法名(); 注意:要在main方法中 ...
- Scrapy去重
一.原生 1.模块 from scrapy.dupefilters import RFPDupeFilter 2.RFPDupeFilter方法 a.request_seen 核心:爬虫每执行一次yi ...
- python StringIO和ByteIO
一.StringIO 1.作用:在内存在读写str # 导入模块 from io import StringIO # 实例化StringIO对象 str_io = StringIO() # 向内存中写 ...
- 将一条路由约束到一组指定的值 约束路由 URL路由
- 第一章001-003课程介绍、计算机网络概述、Internet概述
计算机网络概述 课程安排: 第一章:概述 第二章:物理层 第三章:数据链路层 第四章:网络层 第五章:运输层 第六章:应用层 第七章:网络安全 第八章:因特网上的音频/视频服务 第九章:无线网络 第十 ...
- Linux 常用工具openssh之ssh-add
前言 ssh-add命令是把专用密钥添加到ssh-agent的高速缓存中,从而提高ssh的认证速度 语法 ssh-add [-cDdLlXx] [-t life] [file ...] 选项 -D:删 ...