# Spring源码编译
# 准备工作
# 写在前面
基于Spring 5.1.12 RELEASE + GradleWrapper + jdk1.8.0_131 + idea 2021.2编译
# 环境准备
- maven
- jdk8+
- idea,idea版本无需和我保持一致,其他版本也可
# 源码下载
进入Spring源码github地址 (opens new window)
版本只要是5.x的正式发布(RELEASE)版本就行,因为Spring中IOC,AOP核心分支是不会有变化的,变的只有微小的细节。
# 版本代号讲解
# M
M1
,M2
,...,Mn
中的M
是单词milestone
的简写,意思是里程碑,代表着有重大改进的版本,代码一般变动比较大,不建议使用。
# 构建工具准备
安装源码对应的gradle版本(也可不安装),建议使用GradleWrapper中的gradle。
# Gradle介绍
- Gradle是个构建系统,能够简化你的编译、打包、测试过程。熟悉Java的话,可以把Gradle类比成Maven。
- GradleWrapper的作用是简化Gradle本身的安装、部署。不同版本的项目可能需要不同版本的Gradle,手工部署的话比较麻烦,而且可能产生冲突,所以需要GradleWrapper帮你搞定这些事情。GradleWrapper是Gradle项目的一部分。
- Gradle无需花时间去深入学习,因为我们在学习源码的过程不会过多涉及到gradle。当然有兴趣可以去学习,但是maven已经够优秀了,Gradle暂时应该也没有办法替代maven。
- GradleWrapper在该文件中有体现,相当于远程自动下载gradle到本地(所以你可以下载gradle,也可以不下,因为可以使用GradleWrapper远程的统一版本):
spring-framework-5.1.12.RELEASE\gradle\wrapper\gradle-wrapper.properties
。所以如果你需要下载也最好下载该链接对应的gradle版本
# 修改build.gradle
这个文件就相当于Maven的pom.xml的仓库地址,我们需要修改以下两个地方。
- 添加阿里云镜像仓库,加快依赖下载速度
- 将
compileKotlin
的版本修改为1.3,这是为了解决idea版本过高导致编译报错的问题,如果是2019版本及以前的idea版本则无需修改
configure(allprojects) { project ->
// other config
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
mavenCentral()
maven { url "https://repo.spring.io/libs-spring-framework-build" }
maven { url "http://repo.springsource.org/plugins-release" }
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
apiVersion = "1.3"
languageVersion = "1.3"
}
}
// other config
}
# 编译工作
# 代码编译
- 找到右侧的gradle菜单,gradle -> Spring -> Tasks -> build -> build,点击build即可
首次构建由于有很多依赖需要下载,时间会有点长,耐心等待即可
# 常见问题
# 1. Language version 1.1 is no longer supported; please use version 1.3 or greater.
出现这个问题应该是由kotlin编译版本导致的,其根本原因是你的idea版本太新,项目版本太老。
# 解决方案
- 降低idea版本, 可以使用2019
- 提升项目kotlin版本,前面提到了,将版本修改为1.3即可,亲测有用
# 2. 找不到cglib和objenesis相关的包, 类似于异常:java: 程序包org.springframework.objenesis.instantiator不存在
# 解决方案
添加build before task
cglibRepackJar
和objenesisRepackJar
后,重新点击build即可
cglibRepackJar,gradle -> Spring -> Tasks -> other -> cglibRepackJar,右键选择execute build before
objenesisRepackJar,gradle -> Spring -> Tasks -> other -> objenesisRepackJar,右键选择execute build before
# 测试工作
测试spring的ioc功能
# 添加模块
创建模块spring-test-ioc
# 添加依赖
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testCompile group: 'junit',name: 'junit',version: '4.12'
compile(project(":spring-context"))
compile(project(":spring-instrument"))
}
# 添加任意Service
package cn.com.grasswort.test;
import org.springframework.stereotype.Service;
/**
* The type IntelliJ IDEA.
* <p>
*
* @author liuxiaolu
* @date 2021/12/1
*/
@Service
public class UserServiceImpl {
public void sayHi() {
System.out.println("Hello Spring!");
}
}
# 添加Main方法
package cn.com.grasswort.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* The type IntelliJ IDEA.
* <p>
*
* @author liuxiaolu
* @date 2021/12/1
*/
@Configuration
@ComponentScan("cn.com.grasswort.test")
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainStat.class);
UserServiceImpl bean = context.getBean(UserServiceImpl.class);
bean.sayHi();
}
}
# 结果验证
输出Hello Spring!即为编译成功
# 编译aop模块
当我们需要调试aop的时候,这时候,我们需要引入aspects的注解,这个时候我们需要引入spring-aspects模块,但是这个模块有.aj文件是需要ajc编译器才能编译的
下载aspectj-1.9.6.jar 包 (opens new window)
一路点击next即可
注意需要记住最后一步的安装目录
安装idea插件
然后在settings--Compiler--Java Compiler中的use compiler:选择Ajc
使用aspectJ编译项目
配置完成后,我们需要编译一下aop,和aspectJ项目, file-project -> structure-modules
spring-aop模块和spring-aspects模块分别执行
安装后效果如下
- 最后执行build project