学习源码个人建议还是当一份源码下来,自己编译运行一下,也方便做笔记等。虽然过程中会有一点磕绊,但整体来说,Spring的源码环境搭建还是比较容易的。
准备环境
-
源码
- github.com/spring-proj…
- master等其他版本可能为spring内部开发人员使用的,会包含一些他们内部仓库才有的东西,所以最好切到某个relase的tag下。
- 我们这里选择当前最新的relase版本
-
gradle
- 目前最新的spring使用了gradle作为系统构建器
- 虽然源码说内置了一个gradle环境,不需要我们在自己环境中配置gradle,但是我在编译时候出现了一些问题,所以建议还是自己环境配一个。
- spring对gradle的版本也有要求,但是官网没有说,我最终使用的gradle版本是
gradle-5.6.4。(在编译过程中,spring也会自动下载需要的版本)
-
jdk
-
官方上说jdk8就行,但是如果直接使用Oracle的jdk8是有问题的,会有部分类缺失。
-
网上查阅有人使用Orcale的jdk11解决了,但是我们配置了依然不好使,最后使用的是官方给的链接的open-jdk。
To build you will need Git and JDK 8 update 262 or later.
-
我使用的jdk版本为
-
开始编译
为了防止意外,最好紧跟spring文档的步骤来:官方指导
一些调整
因为我单独下了一个open-jdk,但是我系统当前环境默认的jdk版本还是jdk8,所以我们需要修改下编译脚本,让它使用我们指定的jdk的版本。
主要就是修改gradlew脚本下面这段:(如果你是windows系统就修改gradlew.bat)
我的修改如下:
# 这里指定你配置的jdk位置
JAVA_TMP_HOME=/Users/***/workspace/env/jdk/open-jdk-11.0.10
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_TMP_HOME" ] ; then
if [ -x "$JAVA_TMP_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_TMP_HOME/jre/sh/java"
else
JAVACMD="$JAVA_TMP_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_TMP_HOME
官网步骤
./gradlew build- 下载需要的gradle版本以及相关 依赖,并且会执行所有的测试case。这个步骤会花费比较长时间。
- 一般情况下,就能编译通过了,如下:
- 导入idea
- 参考官方文档
- 注意设置下Project对应的JDK版本,以及Gradle版本。
- 具体步骤
- 预编译:
./gradlew :spring-oxm:compileTestJava - 导入gradle项目,等待idea 下载依赖以及index过程
- 排除
spring-aspects模块
- 预编译:
- 最终导入完成如图:
测试
我们添加一个新的gradle模块:spring-samples
-
添加相关的依赖,修改
build.gradle添加如下:dependencies { compile(project(":spring-context")) testCompile group: 'junit', name: 'junit', version: '4.12' } jar.enabled(true) -
添加一个启动类MainApplication以及一个HelloWorld的bean实体,如图
-
里面内容如下:
- MainApplication
@Configuration // 扫描路径 @ComponentScan("org.springframework.samples") public class MainApplication { public static void main(String[] args) { // 基于注解的容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainApplication.class); String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); Stream.of(beanDefinitionNames).forEach(System.out::println); // 获取helloworld bean HelloService helloServiceImpl = applicationContext.getBean("helloServiceImpl", HelloService.class); helloServiceImpl.sayHello(); } }- HelloWorld Bean
public interface HelloService { String sayHello(); } @Service public class HelloServiceImpl implements HelloService { @Override public String sayHello() { System.out.println("Hello World !"); return "HelloWorld!"; } } -
运行
main方法,环境搭建完毕。