Spring Framework 5.2.19源码下载和编译

Spring 下载编译

进入spring-framework官网
点击如图所示github按钮,spring-framework的源码托管在了github上面,直接去github搜索也是可以的

Spring Framework 5.2.19源码下载和编译_第1张图片

  • M1…M2(Milestone):里程碑版本,在版发布之前会出几个里程碑的版本。使用snapshot版本开发了一个时间,觉得最近写代码杠杠的,那么就整几个里程碑版本记录下吧
  • RC1…RC2(Release Candidates):发布候选,内部开发到一定阶段了,各个模块集成后,经过细心的测试整个开发团队觉得软件已经稳定没有问题了,可以对外发行了。
  • release:正式版本。发布候选差不多之后,那么说明整个框架到了一定的阶段了,可投入市场大面积使用了,那么发布出去,让广大用户来吃吃香吧。

这里我选择5.2.19 release版本

Spring Framework 5.2.19源码下载和编译_第2张图片
然后使用git clone(需要自己下载git工具) 下来
Spring Framework 5.2.19源码下载和编译_第3张图片

git clone https://github.com/spring-projects/spring-framework.git

Spring Framework 5.2.19源码下载和编译_第4张图片
cd 到源码文件夹下面

cd spring-framework

Spring Framework 5.2.19源码下载和编译_第5张图片

git checkout 925b078

Spring Framework 5.2.19源码下载和编译_第6张图片

添加阿里云镜像仓库

找到源码文件夹下面的build.gradle文件(相当于maven的pom),编辑修改镜像仓库配置,加快下载项目依赖的速度
在279行的位置(版本不同可能不一样,也可以使用编辑器搜索功能搜索repositories)

maven {url 'https://maven.aliyun.com/nexus/content/groups/public/'} 
maven {url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}

Spring Framework 5.2.19源码下载和编译_第7张图片

同时,我们在github上面可以看到,官网写的有教程来教我们怎么编译spring源码
Build from Source
Spring Framework 5.2.19源码下载和编译_第8张图片
点击上方红框进入,我们选择使用IDEA来查看spring源代码
有如下图三个步骤:
(注意:第三步本博客并没有执行,没有出现错误情况,并且这个bug的issue最近一次更新也是在9年之前,估计在新版本中早已经修复了,如果有问题,就unload这个spring-aspects子项目,然后重新build spring framework)
Spring Framework 5.2.19源码下载和编译_第9张图片
这里写着我们需要预编译spring-oxm,使用gradle脚本文件
gradlew脚本文件会自动帮你下载gradle(放弃,下载太慢了,还是手动下载把)

按照gradlew给我下的这个版本下载(避免出问题),版本信息在gradle/wrapper/gradle-wrapper.properties配置文件中
gradle下载地址

在这里插入图片描述
gradle-5.6.4-bin.zip 文件下载到电脑本地以后,更改spring-framework源码中的gradle/wrapper/gradle-wrapper.properties配置文件

file:///为本地文件传输协议(你的gradle文件放在哪里,你就写那个路径)

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
# distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
distributionUrl=file\:///D\:/maintenance/gradle-5.6.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

然后使用如下命令预编译(使用git终端)spring-oxm

./gradlew :spring-oxm:compileTestJava

Spring Framework 5.2.19源码下载和编译_第10张图片
Spring Framework 5.2.19源码下载和编译_第11张图片

你可能会遇到如下错误
ERROR: JAVA_HOME is set to an invalid directory
你可能需要更改一下你的系统环境变量JAVA_HOME,不能带分号,也不能带bin目录
Spring Framework 5.2.19源码下载和编译_第12张图片
然后系统的path变量里面你可以追加设置这个,让电脑依然可以找到java
在这里插入图片描述

IDEA 构建

使用IDEA打开spring framework项目,就会自动构建
Spring Framework 5.2.19源码下载和编译_第13张图片
图中的爆红

POM relocation to an other version number is not fully supported in Gradle : xml-apis:xml-apis:2.0.2 relocated to xml-apis:xml-apis:1.0.b2.
Please update your dependency to directly use the correct version 'xml-apis:xml-apis:1.0.b2'.
Resolution will only pick dependencies of the relocated element.  Artifacts and other metadata will be ignored.

解决方案:
修改引入方式,修改bulid.gradle,搜索configurations.all,添加如下内容:(不过我没管这个爆红,暂时使用没有发现问题)

可见stack overflow这篇Exclude transitive dependency in Gradle [duplicate]

configurations.all {
    resolutionStrategy {
        force 'xml-apis:xml-apis:1.0.b2'
    }
}

测试

新建一个gradle的module
Spring Framework 5.2.19源码下载和编译_第14张图片
给自己的模块加依赖,里面的很多注解和应用上下ApplicationContext文我们后面都要用到

compile(project(":spring-context"))

Spring Framework 5.2.19源码下载和编译_第15张图片
编写一个简单的applicationContext获取容器用的bean,用来测试Spring源码构建编译过程是否成功

实体类User

public class User {

	private String id;
	private String userName;
	private String age;
	private String work;
	private String salary;

	private StringBuilder stringBuilder = new StringBuilder();

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getWork() {
		return work;
	}

	public void setWork(String work) {
		this.work = work;
	}

	public String getSalary() {
		return salary;
	}

	public void setSalary(String salary) {
		this.salary = salary;
	}


	@Override
	public String toString() {

		stringBuilder.append("User :{");
		stringBuilder.append("id='" + id);
		stringBuilder.append("'\\''");
		stringBuilder.append(", userName='" + userName);
		stringBuilder.append("'\\''");
		stringBuilder.append(", age='" + age);
		stringBuilder.append("'\\''");
		stringBuilder.append(", work='" + work);
		stringBuilder.append("'\\''");
		stringBuilder.append(", salary='" + salary);
		stringBuilder.append("'\\''");
		stringBuilder.append("'}'");


		return stringBuilder.toString();
	}
}

User配置类,从这里获取User 的bean

package com.xt.spring.config;

import com.xt.spring.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {

	@Bean
	public User user() {

		User user = new User();
		user.setId("1");
		user.setUserName("xt");
		user.setAge("24");

		return user;
	}
}

应用程序启动类
@ComponentScan注解也是在spring-context子项目中,指定扫描包com.xt.spring下的component,在程序中通过AnnotationConfigApplicationContext来获取由Spring自动创建的Bean。对于main函数中使用spring的场景,有两个常见的高级容器。一个是ClassPathXmlApplicationContext,基于classpath下的xml配置文件;另一种是AnnotationConfigApplicationContext,基于java配置文件。

如下是他的类图
Spring Framework 5.2.19源码下载和编译_第16张图片

package com.xt.spring;

import com.xt.spring.config.UserConfig;
import com.xt.spring.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.Arrays;

@ComponentScan("com.xt.spring.**")
public class UserApplication {

	public static void main(String[] args) {

		System.out.println("启动...........");
		long startTime = System.currentTimeMillis();
		System.out.println("开始时间:" + startTime + "毫秒");
		ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class);
		User user = context.getBean(User.class);
		System.out.println("信息:" + user.toString());
		System.out.println(context.getBeanDefinitionCount());
		Arrays.stream(context.getBeanDefinitionNames()).forEach(System.out::println);
		long endTime = System.currentTimeMillis();
		System.out.println("结束时间:" + endTime + "毫秒");
		System.out.println("耗时:" + (endTime - startTime) + "毫秒");
	}

}

如下所示,已经获取并创建了自定义的bean了(可能你会有中文乱码问题,见下面部分内容)
Spring Framework 5.2.19源码下载和编译_第17张图片

有关IDEA控制台乱码问题

修改 IntelliJ IDEA 全局编码、项目编码、属性文件编码

上方导航栏“File→Settings…”进入配置页面,在“Editor”中下滑找到“File Encodings”,分别将 Global Encoding、Project Encoding、Default encoding for properties files 都设置为 UTF-8。在重启之后运行程序检查控制台信息,如果不管用请执行下面的步骤。
Spring Framework 5.2.19源码下载和编译_第18张图片

IntelliJ IDEA 中自定义虚拟机选项

上方导航栏“Help→Etit Custom VM Options…”进入自定义虚拟机选项页面。
Spring Framework 5.2.19源码下载和编译_第19张图片
在 idea64.exe.vmoptions 文件尾加上-Dfile.encoding=UTF-8。在重启之后运行程序检查控制台信息,一般到了这步问题就解决了,当然如果不管用请执行下面的超级步骤。
Spring Framework 5.2.19源码下载和编译_第20张图片

直接修改 IntelliJ IDEA 配置文件的编码信息

我们打开 IntelliJ IDEA 在本地的安装目录,找到下面两个文件,使用记事本打开,在最后一行添加-Dfile.encoding=UTF-8 即可。在重启之后运行程序检查控制台信息,问题解决!
Spring Framework 5.2.19源码下载和编译_第21张图片
Spring Framework 5.2.19源码下载和编译_第22张图片
Spring Framework 5.2.19源码下载和编译_第23张图片

spring源代码各个模块作用

主要模块:

spring-core:核心模块 依赖注入IOC和DI的最基本实现
spring-beans: Bean工厂与装配
spring-context:上下文,即IOC容器
spring-context-support:对IOC的扩展,以及IOC子容器
spring-context-indexer:类管理组件和Classpath扫描
spring-expression:表达式语句

切面编程:

 spring-aop:面向切面编程,CGLIB,JDKProxy
 spring-aspects:集成AspectJ,Aop应用框架
 spring-instrument:动态Class Loading模块

数据访问与集成:

spring-jdbc:提供JDBC主要实现模块,用于简化JDBC操作
spring-tx: spring-jdbc事务管理
spring-orm:主要集成Hibernate,jpa,jdo等
spring-oxm:将java对象映射成xml数据或将xml映射为java对象
spring-jms:发送和接受消息

web组件:

spring-web:提供了最基础的web支持,主要建立在核心容器上
spring-webmvc:实现了spring mvc的web应用
spring-websocket:主要与前端页的全双工通讯协议
spring-webflux:一个新的非阻塞函数式Reactive Web框架

报文:

spring-messaging: 4.0加入的模块,主要集成基础报文传送应用

测试:

spring-test:测试组件

集成兼容:

spring-framework-bom:解决不同模块依赖版本不同问题

References:

  • https://kaven.blog.csdn.net/article/details/120477277
  • https://blog.csdn.net/u013933720/article/details/78363509
  • https://blog.csdn.net/adai_study/article/details/108379625?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-2.nonecase
  • https://www.cnblogs.com/wujing0510/p/13806269.html
  • https://www.cnblogs.com/liuyangfirst/p/13526619.html
  • https://cloud.tencent.com/developer/article/1795283
  • https://blog.csdn.net/u010900754/article/details/99706436

(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料、官方文档和自己的实践,整理的不足和错误之处,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源和分享的知识。)

你可能感兴趣的:(spring)