身为一个合格java程序员,居然没有去编译过Spring 源码!!!
前言:
从事java开发工作三载有余, 咋子说三年工作中java框架就是Spring 全家桶这一套。要是说对这个框架已经非常熟悉、了然于胸。 其实也没有最主要是对这个框架的使用和了解些基本的原理,可以熟练使用它来完成日常的业务开发,然后在这个过程中就会发现Spring 软件框架的设计的精妙😀。 通过对Spring 源码的学习让自己加深对 编程思想、设计模式的认知。so... 便想重新从源码的角度去学习Spring,一方面可以巩固之前学习的设计模式及其应用用,另一方面提高一下自己阅读源码的能力。最后希望自己可以坚持阅读下去 💪 💪 💪。
环境
- git-version: git下载
- java-versioin: 1.8
- Idea: IntelliJ IDEA 2020.1 (Ultimate Edition)
- Gradle-version:gradle-5.6.2
- spring 5.x
拉取Spring源码
github 拉取代码
-
首先在 github 上面搜索
spring选择点击 spring-projects 这个仓库,进入以下界面
在这个界面中拉取代码即可。
-
Spring 源码获取方式有两种
1. 直接拉取代码到本地后切换分支
- 复制git 仓库地址
git clone git@github.com:spring-projects/spring-framework.git [-b branch(指定分支名称)]- 在电脑建好对应的文件夹,使用git 命令行拉取代码(建议使用
ssh协议方式拉取)
-
下载完成(因为在github中可能需要亿点点时间)后,使用
git bash进入对应的目录
使用
git命令在本地创建开发分支git checkout -b new_brancha_name tag_name如:git checkout -b 5.2.0 v5.2.0以上步骤完成之后进入目录如图所示:
2. 使用fork 到自己的仓库中方式
> fork是“分叉”、“复制”的意思;fork可以复制出一个仓库的新拷贝,包含了原有库中的所有提交记录,fork后这个代码库是完全独立的,可以在自己的库中做任何修改,也可以向原来的库提交合并请求。- 在
spring-framework中fork到自己github的Repositories中
步骤一:
步骤二:
步骤三:
- 完成以上步骤,按照【1】 中的将代码clone 到本地,并选择需要编译、阅读源码的分支。
编译前准备工作
按照上面的步骤来,会得到下面的一个目录机构,之后就可以对spring 源码进行编译了。
进入目录后我们发现Spring使用的Gradle来构建的(3.x 使用的还是maven 具体是那个版本换到gradle不清楚,相较于前者编译是速度杠杠滴)。这里先不着急把项目导入idea,需要先安装Gradle,安装完成后改些配置。
这里为啥要先改配置的主要原因是
1、 学习过Gradle的老师都知道使用Gradle 构建的java项目都有一个gradle/wapper文件夹 (wrapper包装器),
gradle-wrapper.properties文件中有配置项目需要的gradle下载地址。 如distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip,warapper包装器的作用:用于解决实际开发中可能会遇到的不同的项目需要不同版本的 Gradle问题。也是Gradle 官方推荐的做法。如果不想在本地安装Gradle 可以直接使用项目GradleWrapper中自带的版本。2、需要改动Gradle中对应的maven镜像源由国外的改成阿里的中央仓库,主要原因是为了快速的下载jar包,让编译快亿点。
-
在项目目录找到
/e/openSourceProject/spring-framework/gradle/wrapper中的gradle-wrapper.properties文件里面有对应该Spring的Tag使用的gradle版本。下载对应的版本(如果不使用对应的gradle版本编译的时候会报一些奇奇怪怪的错,别问为啥😭😭😭)gradle下载地址 -
gradle下载放到本地的目录,修改
gradle-wrapper.properties文件distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip改成distributionUrl=file\:///D:/JetBrains/gradle-5.6.2-bin/gradle-7.2-bin.zip。 -
分别配置
build.gradle和settings.gradle国内镜像源-
build.gradle
repositories { maven { url "https://maven.aliyun.com/repository/public" } maven { url "https://maven.aliyun.com/repository/gradle-plugin"} mavenCentral() maven { url "https://repo.spring.io/libs-spring-framework-build" } } -
settings.gradle
pluginManagement { repositories { maven { url "https://maven.aliyun.com/repository/public" } maven { url "https://maven.aliyun.com/repository/gradle-plugin"} mavenCentral() gradlePluginPortal() maven { url "https://repo.spring.io/release" } } }
-
完成以上准备动作接下来开始编译,cmd 打开本地spring项目目录:
执行Gradle命令:./gradlew :spring-oxm:compileTestJava 开始编译,如图所示:
等待几分钟☕☕☕☕...最后你会看到如下信息
到这里为止Spring源码就编译成功了😄。
导入Idea
源码编译成功,需要阅读源代码和Debug就得导入到Idea中,打开Idea-> File->New->Project From existing Source->选择spring项目目录->选中build.gradle-> Open file as Project 等待几分钟。Idea在Builde过程中没有报错就可以进行下面的测试了。
测试
在Spring项目下新建子模块 File-> Project Structure->Modules-> + -> New Module 如图
目录结构如下如所示:
在build.gradle中加入对应的依赖
plugins {
id 'java'
}
group 'org.springframework'
version '5.2.0.RELEASE'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
implementation(project(":spring-context"))
implementation(project(":spring-beans"))
implementation(project(":spring-core"))
}
配置类:
package com.chou.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author Axel
* @version 1.0
* @className AppConfig
* @description TODO
* @date 2022/8/7 11:21
*/
@Configuration
@ComponentScan(value = "com.chou.spring")
public class AppConfig {
// 扫描com.chou.spring 下面所有的bean
}
业务类:
package com.chou.spring.service;
import org.springframework.stereotype.Service;
/**
* @author Axel
* @version 1.0
* @className HolleService
* @description TODO
* @date 2022/8/7 11:28
*/
@Service
public class HelloService {
public void hello(){
System.out.println("hello spring source code !");
}
}
测试类:
package com.chou.spring;
import com.chou.spring.config.AppConfig;
import com.chou.spring.service.HelloService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author Axel
* @version 1.0
* @className ChouSpringTest
* @description TODO
* @date 2022/8/7 11:29
*/
public class ChouSpringTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
HelloService helloService = applicationContext.getBean(HelloService.class);
helloService.hello();
}
}
运行 ChouSpringTest 结果如下:
到此为止Spring源码编译就结束了🤡🤡🤡