SpringFramework-3.x以前的版本都在托管在sourceforge.net网站,3.x以后才开源在Github,而笔者想要SpringFramework-1.0,所以先去sourceforge.net网站(https://sourceforge.net/projects/springframework/files/springframework/)下载源码。
为什么选择1.0呢?1.0是官方的第一个文档完备的正式版,相对现在5.x而言,功能还比较简单,但Spring核心功能已经具备,是学习Spring的最原始、难度相对较小的一个版本。下面附一张1.0的概览图:
官网(http://ant.apache.org)下载Ant安装包,然后配置环境变量:
ANT_HOME=D:\apache-ant-1.9.14
path=%ANT_HOME%\bin
这里注意Ant的版本,官网介绍中说明了1.9.x需要jdk5以上,1.10.x需要jdk8以上。
笔者实践时jdk是1.8,下载了1.9.x,编译时报错了:
显示是JDK版本高了,SpringFramework-1.0源码用了1.4的语法,这里重新下载jdk1.4。
去官方(https://www.oracle.com/technetwork/java/archive-139210.html)找jdk1.4安装包,这里笔者一开始也踩到了“坑”。
笔者在oracle官方下载一个j2eesdk-1_4_03-windows.exe安装包,完成后,安装目录下面有个jdk目录:
进入jdk目录,使用java -version
命令显示却是java version "1.5.0_06"
,怀疑自己下载错了,应该安装java SE,而不是j2ee。
(笔者上面提供的下载地址是对的)
重新下载一个j2sdk-1_4_2_19-windows-i586-p.exe,再试一次,这次成功安装了jdk1.4。
笔者习惯性的使用file - open,这种打开工程的方式在maven工程上从未翻车,但是SpringFramework-1.0是用Ant构建的,这种方式导入源码虽然不会报错,但是idea本身识别不了package和src。
尝试用import project试一下,这次成功,idea成功加载了这个项目。
这里有个小误会,笔者以为:
①Ant默认使用window环境变量配置的jdk1.8;
②而SpringFramework使用在project structure配置的jdk1.4;
编译报错说明①是没错的,但Ant也会使用jdk1.8去build SpringFramework的工程。因为jdk8的很多接口发生了改变,导致SpringFramework-1.0用jdk8编译时发生了很多接口不匹配的问题,具体如下:
[javac] (请使用 -source 5 或更高版本以将 'enum' 用作关键字)
[javac] E:\gitlocal\spring-framework-1.0\src\org\springframework\web\util\WebUtils.java:220: 警告: 从发行版 5 开始, 'enum' 为关键字, 而不用作标识符
[javac] String paramName = (String) enum.nextElement();
[javac] ^
[javac] (请使用 -source 5 或更高版本以将 'enum' 用作关键字)
[javac] E:\gitlocal\spring-framework-1.0\src\org\springframework\jdbc\datasource\DriverManagerDataSource.java:53: 错误: DriverManagerDataSource不是抽象的, 并且未覆盖CommonDataSource中的抽象方法getParentLogger()
[javac] public class DriverManagerDataSource extends AbstractDataSource implements SmartDataSource {
[javac] ^
[javac] E:\gitlocal\spring-framework-1.0\src\org\springframework\jdbc\support\lob\OracleLobHandler.java:228: 错误: 对setBlob的引用不明确
[javac] ps.setBlob(parameterIndex, null);
[javac] ^
[javac] PreparedStatement 中的方法 setBlob(int,Blob) 和 PreparedStatement 中的方法 setBlob(int,InputStream) 都匹配
上面只截取了一部分日志,能看出这是用1.8编译导致的。
既project structure配置的jdk1.4并没有用来编译SpringFramework源码。
OK,那把JAVA_HOME设置成jdk1.4,再试一次,结果如下:
$ ant build
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/tools/ant/launch/Launcher (Unsupported major.minor version 49.0)
显示当前jdk版本不支持当前Ant,现在出现了尴尬的矛盾局面,JDK版本既要符合SpringFramework要求,也要支持Ant,否则编译失败,只能重新安装Ant了。
再次安装了apache-ant-1.5.4-bin.zip,重新编译,这次成功!
E:\gitlocal\spring-framework-1.0>ant build
Buildfile: build.xml
compileattr:
[attribute-compiler] Generated attribute information for 0 classes. Ignored 0 classes.
build:
BUILD SUCCESSFUL
Total time: 1 second
(笔者使用window cmd编译的,IDEA的terminal依然不成功)
E:\gitlocal\spring-framework-1.0>ant tests
Buildfile: build.xml
compileattr:
[attribute-compiler] Generated attribute information for 0 classes. Ignored 0 classes.
build:
compiletestattr:
[attribute-compiler] Generated attribute information for 0 classes. Ignored 1 classes.
buildtests:
tests:
......省略
[junit] Testsuite: org.springframework.web.util.TagUtilsTestSuite
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.114 sec
[junit] Testcase: testTagUtils took 0.001 sec
BUILD SUCCESSFUL
Total time: 1 minute 39 seconds
这次OK了,至此SpringFramework-1.0源码可以在本地调试运行了。中间走了很多弯路,踩了很多坑,复盘如下:
总结:
随着技术发展,很多“强大”的工具帮我完成琐碎的活儿,把我们解放出来了,好处想而易见。但同时也有隐患,那就是渐渐我们失去了研究基本方法的动力和动机,以至于抛开这些工具,我们将变得无所适从。愿我们在追捧新技术同时,也不要忘了基础理论和方法,比如我们既要会使用spring-boot搭建写代码,也要会使用servlet。