Spring 5.3.x 源码构建编译


1. 确定最新源码版本,源码地址

在这里插入图片描述

最新版本 5.3.21
源码github地址


2. 源码编译

2.1 github 源码编译指南

在这里插入图片描述
在这里插入图片描述

克隆代码

git clone git@github.com:spring-projects/spring-framework.git
cd spring-framework

编译

./gradlew build

提示:以下操作与github源码编译步骤略有不同


2.2 源码下载(建议大家fork到自己仓库、在自己仓库进行克隆)

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

2.3 指定tag v5.3.21 分支切换

cd spring-framework
git checkout -b v5.3.21 origin/v5.3.21

2.4 gradle文件远程仓库修改

2.4.1 修改build.gradle,添加gradle依赖下载远程仓库

repositories {
		maven {
			url 'https://maven.aliyun.com/repository/public/'
		}
		maven {
			url 'https://maven.aliyun.com/repository/spring/'
		}
		mavenLocal()
		mavenCentral()
		gradlePluginPortal()
		maven { url "https://repo.spring.io/release" }
	}

2.4.2 修改setting.gradle,添加gradle插件下载远程仓库

pluginManagement {
	repositories {
		maven {
			url 'https://maven.aliyun.com/repository/public/'
		}
		maven {
			url 'https://maven.aliyun.com/repository/spring/'
		}
		mavenLocal()
		mavenCentral()
		gradlePluginPortal()
		maven { url "https://repo.spring.io/release" }
	}
}

2.5 项目构建

2.5.1 跳过测试进行编译(减少等待时间)

./gradlew build -x test

2.5.2 构建结果

在这里插入图片描述
添加了远程仓库地址后、构建速度明显快了很多


2.5.3 构建过程中,出现ge.spring.io身份验证错误

注释setting.gradle配置文件认证插件

plugins {
	id "com.gradle.enterprise" version "3.9"
	// id "io.spring.ge.conventions" version "0.0.9"
}

2.5.4 再次执行构建命令、构建成功

在这里插入图片描述


3. idea 打开项目

3.1 项目构建

3.1.1 idea gradle配置

在这里插入图片描述


3.1.2 等待idea加载、执行gradle插件任务、导入项目

在这里插入图片描述


3.1.3 项目导入成功

在这里插入图片描述


3.2 新建测试模块进行测试

3.2.1 新建module

file —> New —> Module
在这里插入图片描述
在这里插入图片描述


3.2.2 修改新建模块对应build.gradle,引入spring-context依赖
dependencies {
    implementation(project(":spring-context"))
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}

关于引入依赖模块的补充:

有些文章引入的依赖模块是这样的

dependencies {
    implementation(project(":spring-context"))
    implementation(project(":spring-beans"))
    implementation(project(":spring-core"))
    implementation(project(":spring-aop"))
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}

打开spring-context模块的spring-context.gradle文件
在这里插入图片描述
根据依赖传递的特性、在spring-context模块中已经引入了其余三个模块的依赖、不需要重复引入
如果将依赖作用范围api替换成implementation,则需要在新建模块中进行额外三个依赖的引入、感兴趣的小伙伴可以进行测试

有关gradle依赖api、implementation的区别、官方文档解释


3.2.3 测试类进行测试
public class AppConfig {

	public void test(){
		System.out.println("hello World!");
	}
}
public class IocTest {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		AppConfig appConfig = applicationContext.getBean("appConfig", AppConfig.class);
		appConfig.test();
	}
}

3.2.4 程序执行异常(jdk.jfr不存在)

在这里插入图片描述
程序包jdk.jfr不存在 这个是jdk11添加的新特性, 用于监控应用的运行情况。我们使用的是jdk8版本、解决方案:

  1. 切换jdk版本到jdk11
  2. 注释掉相关类的代码(我使用的这种)
/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.metrics.jfr;

//import jdk.jfr.Category;
//import jdk.jfr.Description;
//import jdk.jfr.Event;
//import jdk.jfr.Label;

//import com.sun.org.glassfish.gmbal.Description;

/**
 * {@link Event} extension for recording {@link FlightRecorderStartupStep}
 * in Java Flight Recorder.
 *
 * <p>{@link org.springframework.core.metrics.StartupStep.Tags} are serialized
 * as a single {@code String}, since Flight Recorder events do not support complex types.
 *
 * @author Brian Clozel
 * @since 5.3
 */
//@Category("Spring Application")
//@Label("Startup Step")
//@Description("Spring Application Startup")
//class FlightRecorderStartupEvent extends Event {
class FlightRecorderStartupEvent  {

	public final long eventId;

	public final long parentId;

//	@Label("Name")
	public final String name;

//	@Label("Tags")
	String tags = "";

	public FlightRecorderStartupEvent(long eventId, String name, long parentId) {
		this.name = name;
		this.eventId = eventId;
		this.parentId = parentId;
	}

	public void setTags(String tags) {
		this.tags = tags;
	}

}

/*
 * Copyright 2012-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.core.metrics.jfr;

import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.NonNull;

/**
 * {@link StartupStep} implementation for the Java Flight Recorder.
 * <p>This variant delegates to a {@link FlightRecorderStartupEvent JFR event extension}
 * to collect and record data in Java Flight Recorder.
 *
 * @author Brian Clozel
 */
class FlightRecorderStartupStep implements StartupStep {

	private final FlightRecorderStartupEvent event;

	private final FlightRecorderTags tags = new FlightRecorderTags();

	private final Consumer<FlightRecorderStartupStep> recordingCallback;


	public FlightRecorderStartupStep(long id, String name, long parentId,
			Consumer<FlightRecorderStartupStep> recordingCallback) {

		this.event = new FlightRecorderStartupEvent(id, name, parentId);
//		this.event.begin();
		this.recordingCallback = recordingCallback;
	}


	@Override
	public String getName() {
		return this.event.name;
	}

	@Override
	public long getId() {
		return this.event.eventId;
	}

	@Override
	public Long getParentId() {
		return this.event.parentId;
	}

	@Override
	public StartupStep tag(String key, String value) {
		this.tags.add(key, value);
		return this;
	}

	@Override
	public StartupStep tag(String key, Supplier<String> value) {
		this.tags.add(key, value.get());
		return this;
	}

	@Override
	public Tags getTags() {
		return this.tags;
	}

	@Override
	public void end() {
//		this.event.end();
//		if (this.event.shouldCommit()) {
//			StringBuilder builder = new StringBuilder();
//			this.tags.forEach(tag ->
//					builder.append(tag.getKey()).append('=').append(tag.getValue()).append(',')
//			);
//			this.event.setTags(builder.toString());
//		}
//		this.event.commit();
		this.recordingCallback.accept(this);
	}

	protected FlightRecorderStartupEvent getEvent() {
		return this.event;
	}


	static class FlightRecorderTags implements Tags {

		private Tag[] tags = new Tag[0];

		public void add(String key, String value) {
			Tag[] newTags = new Tag[this.tags.length + 1];
			System.arraycopy(this.tags, 0, newTags, 0, this.tags.length);
			newTags[newTags.length - 1] = new FlightRecorderTag(key, value);
			this.tags = newTags;
		}

		public void add(String key, Supplier<String> value) {
			add(key, value.get());
		}

		@NonNull
		@Override
		public Iterator<Tag> iterator() {
			return new TagsIterator();
		}

		private class TagsIterator implements Iterator<Tag> {

			private int idx = 0;

			@Override
			public boolean hasNext() {
				return this.idx < tags.length;
			}

			@Override
			public Tag next() {
				return tags[this.idx++];
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException("tags are append only");
			}
		}
	}


	static class FlightRecorderTag implements Tag {

		private final String key;

		private final String value;

		public FlightRecorderTag(String key, String value) {
			this.key = key;
			this.value = value;
		}

		@Override
		public String getKey() {
			return this.key;
		}

		@Override
		public String getValue() {
			return this.value;
		}
	}

}


3.2.5 再次运行、spring-context模块下面InstrumentationSavingAgent类找不到

在这里插入图片描述
修改spring-context模块下spring-context.gradle文件

找到以下内容

optional(project(":spring-instrument"))

替换成

implementation(project(":spring-instrument"))

最后刷新gralde依赖

3.2.5 执行程序测试、可以正常执行

在这里插入图片描述

3.2.6 进行aop测试,如果引入@Aspect注解找不到,修改spring-aop模块下spring-aop.gradle文件

找到以下内容

optional("org.aspectj:aspectjweaver")

替换成

api("org.aspectj:aspectjweaver")

最后刷新gralde依赖

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值