spring源码调试环境搭建

1. 获取spring-framework源码

1.1 clone方式

git clone https://github.com/spring-projects/spring-framework.git
cd spring-framework
git checkout 5.2.x # 切换到你需要的分支

1.2 download方式

访问spring的github地址(https://github.com/spring-projects/spring-framework),然后切换到你需要的分支,进行源码包下载。

如下图:
在这里插入图片描述
在这里插入图片描述

2. Spring 源码结构

获取到spring源码后,导入到IDEA中,代码结构如下图:
在这里插入图片描述

3. build

接下来进行代码构建,在IDEA右侧你会看到一个Gradle工具栏,点开会看到如下所示内容,找到下图红框所示命令,点击进行构建,构建过程中如果某个模块构建失败,可以先单独构建该模块,成功后,再整体构建。

在这里插入图片描述

看到下图状态,则代表构建成功。
在这里插入图片描述

4. 添加自定义调试模块

4.1 新增模块

按下面截图所示步骤可以快速创建一个基本的gradle模块。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.2 修改build.gradle文件

模块创建好之后只有一个build.gradle文件,可以在里面添加需要调试的模块,如下:

plugins {
    id 'java'
}

group 'org.springframework'
version '5.2.20.BUILD-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // ========= 添加调试模块 start ===========
    compile(project(":spring-beans"))
    compile(project(":spring-core"))
    compile(project(":spring-context"))
    compile(project(":spring-webmvc"))
    compile(project(":spring-jdbc"))
    compile(project(":spring-orm"))
    compile(project(":spring-tx"))
    compile(project(":spring-web"))
    // ========= 添加调试模块 end ===========
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

4.3 添加代码

然后添加代码,构建成如下图结构:

在这里插入图片描述

MyAppContext代码如下:

package com.hamajiao.spring.debug;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyAppContext {

	public static void main(String[] args) {

		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

	}
}

applicationContext.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 					      					http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

4.4 debug调试

完成以上步骤其实就已经可以愉快的操练起来了,按下面方式进行debug,先一睹spring的风采吧!

在这里插入图片描述

5. 常见错误

5.1 Checkstyle错误

错误内容如下:

Execution failed for task ':spring-debug:checkstyleMain'.
> Checkstyle rule violations were found. See the report at: file:///Users/gaoxiang/git/spring-framework/spring-debug/build/reports/checkstyle/main.html
  Checkstyle files with violations: 1
  Checkstyle violations by severity: [error:2]

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.


> Task :spring-debug:checkstyleMain FAILED
[ant:checkstyle] [ERROR] /Users/gaoxiang/git/spring-framework/spring-debug/src/main/java/com/hamajiao/spring/debug/MyAppContext.java:1: header.missing [SpringHeader]
[ant:checkstyle] [ERROR] /Users/gaoxiang/git/spring-framework/spring-debug/src/main/java/com/hamajiao/spring/debug/MyAppContext.java:5:1: 工具类应隐藏 public 构造器。 [HideUtilityClassConstructor]

Execution failed for task ':spring-debug:checkstyleMain'.
> Checkstyle rule violations were found. See the report at: file:///Users/gaoxiang/git/spring-framework/spring-debug/build/reports/checkstyle/main.html
  Checkstyle files with violations: 1
  Checkstyle violations by severity: [error:2]

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

出现以上错误是因为spring使用了ant风格的代码检查,所有的检查规则都在src/checkstyle/checkstyle.xml里面做了配置,如果不想被这些检查烦扰到,可以全部注释掉:

<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="com.puppycrawl.tools.checkstyle.Checker">
	<!-- Suppressions -->
<!--	<module name="SuppressionFilter">-->
<!--		<property name="file" value="${config_loc}/checkstyle-suppressions.xml"/>-->
<!--	</module>-->

	<!-- Root Checks -->
<!--	<module name="io.spring.javaformat.checkstyle.check.SpringHeaderCheck">-->
<!--		<property name="fileExtensions" value="java" />-->
<!--		<property name="headerType" value="apache2"/>-->
<!--		<property name="headerCopyrightPattern" value="20\d\d-20\d\d"/>-->
<!--		<property name="packageInfoHeaderType" value="none"/>-->
<!--	</module>-->
<!--	<module name="com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck">-->
<!--		<property name="lineSeparator" value="lf"/>-->
<!--	</module>-->

	<!-- TreeWalker Checks -->
<!--	<module name="com.puppycrawl.tools.checkstyle.TreeWalker">-->
<!--		&lt;!&ndash; Annotations &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck">-->
<!--			<property name="elementStyle" value="compact" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.MissingOverrideCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.PackageAnnotationCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck">-->
<!--			<property name="allowSamelineSingleParameterlessAnnotation"-->
<!--				value="false" />-->
<!--		</module>-->

<!--		&lt;!&ndash; Block Checks &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck">-->
<!--			<property name="option" value="text" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck">-->
<!--			<property name="option" value="alone" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.blocks.AvoidNestedBlocksCheck" />-->

<!--		&lt;!&ndash; Class Design &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheck" />-->
<!--&lt;!&ndash;		<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck" />&ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.design.MutableExceptionCheck">-->
<!--			<property name="format" value="^.*Exception$" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.design.InnerTypeLastCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck" />-->

<!--		&lt;!&ndash; Type Names &ndash;&gt;-->
<!--		<module name="TypeName">-->
<!--			<property name="format" value="^[A-Z][a-zA-Z0-9_]*(?&lt;!Test)$" />-->
<!--			<property name="tokens" value="CLASS_DEF" />-->
<!--			<message key="name.invalidPattern"-->
<!--				value="Class name ''{0}'' must not end with ''Test'' (checked pattern ''{1}'')." />-->
<!--		</module>-->

<!--		&lt;!&ndash; Coding &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.EqualsHashCodeCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanExpressionCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanReturnCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.StringLiteralEqualityCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedForDepthCheck">-->
<!--			<property name="max" value="3" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedIfDepthCheck">-->
<!--			<property name="max" value="5" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedTryDepthCheck">-->
<!--			<property name="max" value="3" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheck" />-->

<!--		<module name="io.spring.javaformat.checkstyle.filter.RequiresOuterThisFilter" />-->
<!--		<module name="io.spring.javaformat.checkstyle.filter.IdentCheckFilter">-->
<!--			<property name="names" value="logger" />-->
<!--			<module-->
<!--				name="com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck">-->
<!--				<property name="checkMethods" value="false" />-->
<!--				<property name="validateOnlyOverlapping" value="false" />-->
<!--			</module>-->
<!--		</module>-->
<!--		<module name="io.spring.javaformat.checkstyle.check.SpringNoThisCheck">-->
<!--			<property name="names" value="logger" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck" />-->

<!--		&lt;!&ndash; Imports &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck">-->
<!--			<property name="processJavadoc" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck">-->
<!--			<property name="groups" value="java,javax,*,org.springframework" />-->
<!--			<property name="ordered" value="true" />-->
<!--			<property name="separated" value="true" />-->
<!--			<property name="option" value="bottom" />-->
<!--			<property name="sortStaticImportsAlphabetically" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedImports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses"-->
<!--				value="^reactor\.core\.support\.Assert,^org\.slf4j\.LoggerFactory" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedJUnit3Imports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses" value="^junit\.framework\..+" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedJUnit4Imports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses"-->
<!--				value="^org\.junit\.(Test|BeforeClass|AfterClass|Before|After|Ignore|FixMethodOrder|Rule|ClassRule|Assert|Assume)$,^org\.junit\.(Assert|Assume)\..+,^org\.junit\.(experimental|internal|matchers|rules|runner|runners|validator)\..+" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedJUnitJupiterImports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses" value="^org\.junit\.jupiter\..+" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedTestNGImports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses" value="^org\.testng\..+," />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">-->
<!--			<property name="id" value="bannedHamcrestImports"/>-->
<!--			<property name="regexp" value="true" />-->
<!--			<property name="illegalClasses" value="^org\.hamcrest\..+" />-->
<!--		</module>-->

<!--		&lt;!&ndash; Javadoc Comments &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck">-->
<!--			<property name="scope" value="package"/>-->
<!--			<property name="authorFormat" value=".+\s.+"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck">-->
<!--			<property name="allowMissingParamTags" value="true"/>-->
<!--			<property name="allowMissingThrowsTags" value="true"/>-->
<!--			<property name="allowMissingReturnTag" value="true"/>-->
<!--			<property name="allowMissingJavadoc" value="true"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck">-->
<!--			<property name="scope" value="public"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck">-->
<!--			<property name="checkEmptyJavadoc" value="true"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagContinuationIndentationCheck">-->
<!--			<property name="offset" value="0"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">-->
<!--			<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF"/>-->
<!--    		<property name="tagOrder" value="@author, @since, @param, @see, @version, @serial, @deprecated"/>-->
<!--		</module>-->
<!-- 		<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">-->
<!--			<property name="target" value="METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>-->
<!--    		<property name="tagOrder" value="@param, @return, @throws, @since, @deprecated, @see"/>-->
<!--		</module>-->

<!--		&lt;!&ndash; Miscellaneous &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck">-->
<!--			<property name="tokens" value="BLOCK_COMMENT_BEGIN"/>-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.UpperEllCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.ArrayTypeStyleCheck" />-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck" />-->

<!--		&lt;!&ndash; Regexp &ndash;&gt;-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="format" value="^\t* +\t*\S" />-->
<!--			<property name="message"-->
<!--				value="Line has leading space characters; indentation should be performed with tabs only." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpCheck">-->
<!--			<property name="format" value="[ \t]+$" />-->
<!--			<property name="illegalPattern" value="true" />-->
<!--			<property name="message" value="Trailing whitespace" />-->
<!--		</module>-->
<!--		<module-->
<!--			name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="maximum" value="0" />-->
<!--			<property name="format"-->
<!--				value="assertThatExceptionOfType\((NullPointerException|IllegalArgumentException|IOException|IllegalStateException)\.class\)" />-->
<!--			<property name="message"-->
<!--				value="Please use specialized AssertJ assertThat*Exception method." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="id" value="bddMockito"/>-->
<!--			<property name="maximum" value="0"/>-->
<!--			<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)" />-->
<!--			<property name="message" value="Please use BDDMockito." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="id" value="expectedExceptionAnnotation"/>-->
<!--			<property name="maximum" value="0"/>-->
<!--			<property name="format" value="\@Test\(expected" />-->
<!--			<property name="message" value="Please use AssertJ assertions." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="id" value="junit4Assertions"/>-->
<!--			<property name="maximum" value="0"/>-->
<!--			<property name="format" value="org\.junit\.Assert\.assert" />-->
<!--			<property name="message" value="Please use AssertJ assertions." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="id" value="junitJupiterAssertions"/>-->
<!--			<property name="maximum" value="0"/>-->
<!--			<property name="format" value="org\.junit\.jupiter\.api\.Assertions\.assert" />-->
<!--			<property name="message" value="Please use AssertJ assertions." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->
<!--		<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">-->
<!--			<property name="id" value="testNGAssertions"/>-->
<!--			<property name="maximum" value="0"/>-->
<!--			&lt;!&ndash; should cover org.testng.Assert and org.testng.AssertJUnit &ndash;&gt;-->
<!--			<property name="format" value="org\.testng\.Assert(JUnit)?\.assert" />-->
<!--			<property name="message" value="Please use AssertJ assertions." />-->
<!--			<property name="ignoreComments" value="true" />-->
<!--		</module>-->

<!--		&lt;!&ndash; Spring Conventions &ndash;&gt;-->
<!--		<module name="io.spring.javaformat.checkstyle.check.SpringLambdaCheck">-->
<!--			<property name="singleArgumentParentheses" value="false" />-->
<!--		</module>-->
<!--		<module name="io.spring.javaformat.checkstyle.check.SpringCatchCheck" />-->
<!--		<module name="io.spring.javaformat.checkstyle.check.SpringJavadocCheck" />-->
<!--		<module name="io.spring.javaformat.checkstyle.check.SpringJUnit5Check" />-->
<!-- 	</module>-->
</module>

当然如果不想这么粗暴全部注释,可以只注释掉错误对应的检查规则,比如我上面出现的错误,我这里可以注释掉以下两个规则:

<!-- Root Checks -->
<!-- 检查SpringHeader 每个类开头部分必须是版权声明-->
<module name="io.spring.javaformat.checkstyle.check.SpringHeaderCheck">
  <property name="fileExtensions" value="java" />
  <property name="headerType" value="apache2"/>
  <property name="headerCopyrightPattern" value="20\d\d-20\d\d"/>
  <property name="packageInfoHeaderType" value="none"/>
</module>
<!-- 检查HideUtilityClassConstructor 工具类应私有化构造器 并声明为final 避免被创建对象-->
<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck" />

另外你也可以按照规则一一进行修改来满足规则要求,比如将MyAppContext改成如下内容:

/*
 * Copyright 2002-2017 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 com.hamajiao.spring.debug;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class MyAppContext {

	private MyAppContext() {
	}

	public static void main(String[] args) {

		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

	}
}

总之以上三种方法都可以解决这类错误。当然了,这类错误不解决也不会影响你debug,但是作为患有强迫症晚期的我来说,看到任何错误都是无法忍受的!

5.2 某个模块build失败

某个模块build失败的时候,可以先单独构建该模块,成功后,再整体构建。

5.3 连接问题

有些时候网络不稳定会导致依赖下载失败,一般多试几次都可以下载成功的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值