windows下修改、编译、构建spring-framework4.1.8.RELEASE源码

简介: 实战修改spring-framework源码,然后编译构建,最后用写一个demo工程来验证构建成功

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

本篇概览

环境信息

  • 实战涉及的版本如下:
  1. 操作系统:win10 64;
  2. JDK:1.8.0_144;
  3. Maven:3.5.0;
  4. IntelliJ IDEA:2018.1.5(Ultimate Edition);

全文概要

  • 本次实战所有步骤如下:
  1. 下载spring-framwork源码,用IDEA打开此工程;
  2. 修改spring-framework中的类,添加代码;
  3. 编译构建spring-framework,添加到本地maven仓库;
  4. 基于maven创建一个新的demo,使用本地仓库的spring-framework;
  5. 执行demo工程验证修改的代码已经生效;
  • 接下来开始实战吧;

下载spring-framework源码,用IDEA打开此工程

这里写图片描述

  • 解压后,用Intellij IDEA以Gradle工程的形式导入,Gradle版本记得使用2.14.1,如下图:

这里写图片描述

修改spring-framework中的类

  • 本次修改的类是PropertyPlaceholderHelper.java,这个类用来替换字符串中的占位符,本次修改源码的目的如下:
  1. 将替换前后的字符串打印出来用于对比;
  2. 将调用堆栈打印出来,这样我们在学习spring源码时,可以知道处理占位符的时机和位置;
  • 对PropertyPlaceholderHelper.java的具体修改如下所示:
  • 新增一个private方法,用于打印当前堆栈位置:
private void printTrack(String prefix){
    StackTraceElement[] st = Thread.currentThread().getStackTrace();
    if(st==null){
        logger.info("invalid stack");
        return;
    }

    StringBuffer sbf =new StringBuffer();

    for(StackTraceElement e:st){
        if(sbf.length()>0){
            sbf.append(" <- ");
            sbf.append(System.getProperty("line.separator"));
        }
    
        sbf.append(java.text.MessageFormat.format("{0}.{1}() {2}"
                    ,e.getClassName()
                    ,e.getMethodName()
                    ,e.getLineNumber()));
    }
    logger.info(prefix + "\n" + sbf.toString());
}
AI 代码解读
  • 找到方法parseStringValue,注意是protected类型的那个,在该方法的起始位置添加如下两行代码:
protected String parseStringValue(
            String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
    printTrack("start parseStringValue");
    logger.info("before parse : [" + strVal + "]");
AI 代码解读
  • 上述代码先是将parseStringValue被调用的堆栈打印出来,接着将入参strVal打印出来;
  • 在上一步中的parseStringValue方法的结束位置,在return之前增加一行代码,将处理后的字符串打印出来,如下:
    logger.info("after parse : [" + result + "]");
    return result.toString();
}
AI 代码解读
  • 为了避免当前电脑的其他项目用到我们构建的spring版本,我们把版本号改掉,打开gradle.properties文件,修改版本号为"4.1.88.RELEASE",如下:
version=4.1.88.RELEASE
AI 代码解读

编译构建spring-framework

  • 用命令build -x test编译和构建工程,操作如下图所示:

这里写图片描述

  • 等待构建完成之后,用命令install将构建的jar部署到本地maven仓库中,如下图:

这里写图片描述

  • 去本地maven仓库看看,果然已经有文件了,如下图:

这里写图片描述

创建demo,使用本地仓库的spring-framework

  • 基于maven创建一个java应用,以下是步骤:
  • pom.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bolingcavalry</groupId>
    <artifactId>springcoredemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.88.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.88.RELEASE</version>
        </dependency>
    </dependencies>

</project>
AI 代码解读
  • 新增文件:src/main/resources/applicationContext.xml,用于配置bean,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

    <beans>
        <bean class="com.bolingcavalry.bean.Simple"></bean>
    </beans>
</beans>
AI 代码解读
  • 创建一个类:com.bolingcavalry.bean.Simple.java:
public class Simple {
    public void execute() {
        System.out.println("Simple execute method");
    }
}
AI 代码解读
  • 创建启动类com.bolingcavalry.DemoApplication.java:
public class DemoApplication {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("${CONFIG_PATH}");
        Simple bean = context.getBean(Simple.class);
        bean.execute();
        context.close();
    }
}
AI 代码解读
  • 注意以上代码中有个变量${CONFIG_PATH},这个变量的值不在代码和配置文件中,留待运行的时候再设置;
  • 运行DemoApplication.java的时候,注意传入环境变量CONFIG_PATH的值,在IDEAL上的做法如下,点击红框中的"Edit Configurations...":

这里写图片描述

  • 如下图,点击红框中的按钮:

这里写图片描述

  • 如下图,点击红框中的加号,然后添加一个键值对,Name是"CONFIG_PATH",Value是"classpath:applicationContext.xml"

这里写图片描述

  • 配置完毕后,点击下图红框中的绿色三角形按钮,即可运行DemoApplication的main方法,并且刚刚设置的环境变量也生效了:

这里写图片描述

  • 运行结果如下:
C:\jdk\bin\java.exe -javaagent:C:\software\JetBrains\IntelliJIDEA\lib\idea_rt.jar=60748:C:\software\JetBrains\IntelliJIDEA\bin -Dfile.encoding=UTF-8 -classpath C:\jdk\jre\lib\charsets.jar;C:\jdk\jre\lib\deploy.jar;C:\jdk\jre\lib\ext\access-bridge-64.jar;C:\jdk\jre\lib\ext\cldrdata.jar;C:\jdk\jre\lib\ext\dnsns.jar;C:\jdk\jre\lib\ext\jaccess.jar;C:\jdk\jre\lib\ext\jfxrt.jar;C:\jdk\jre\lib\ext\localedata.jar;C:\jdk\jre\lib\ext\nashorn.jar;C:\jdk\jre\lib\ext\sunec.jar;C:\jdk\jre\lib\ext\sunjce_provider.jar;C:\jdk\jre\lib\ext\sunmscapi.jar;C:\jdk\jre\lib\ext\sunpkcs11.jar;C:\jdk\jre\lib\ext\zipfs.jar;C:\jdk\jre\lib\javaws.jar;C:\jdk\jre\lib\jce.jar;C:\jdk\jre\lib\jfr.jar;C:\jdk\jre\lib\jfxswt.jar;C:\jdk\jre\lib\jsse.jar;C:\jdk\jre\lib\management-agent.jar;C:\jdk\jre\lib\plugin.jar;C:\jdk\jre\lib\resources.jar;C:\jdk\jre\lib\rt.jar;D:\github\blog_demos\springcoredemo\target\classes;C:\Users\12167\.m2\repository\org\springframework\spring-core\4.1.88.RELEASE\spring-core-4.1.88.RELEASE.jar;C:\Users\12167\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\12167\.m2\repository\org\springframework\spring-context\4.1.88.RELEASE\spring-context-4.1.88.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-aop\4.1.88.RELEASE\spring-aop-4.1.88.RELEASE.jar;C:\Users\12167\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\12167\.m2\repository\org\springframework\spring-beans\4.1.88.RELEASE\spring-beans-4.1.88.RELEASE.jar;C:\Users\12167\.m2\repository\org\springframework\spring-expression\4.1.88.RELEASE\spring-expression-4.1.88.RELEASE.jar com.bolingcavalry.DemoApplication
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper printTrack
信息: start parseStringValue
java.lang.Thread.getStackTrace() 1,559 <- 
org.springframework.util.PropertyPlaceholderHelper.printTrack() 231 <- 
org.springframework.util.PropertyPlaceholderHelper.parseStringValue() 132 <- 
org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders() 126 <- 
org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders() 204 <- 
org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders() 178 <- 
org.springframework.core.env.AbstractEnvironment.resolveRequiredPlaceholders() 571 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.resolvePath() 122 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.setConfigLocations() 80 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 137 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 83 <- 
com.bolingcavalry.DemoApplication.main() 14
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: before parse : [${CONFIG_PATH}]
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper printTrack
信息: start parseStringValue
java.lang.Thread.getStackTrace() 1,559 <- 
org.springframework.util.PropertyPlaceholderHelper.printTrack() 231 <- 
org.springframework.util.PropertyPlaceholderHelper.parseStringValue() 132 <- 
org.springframework.util.PropertyPlaceholderHelper.parseStringValue() 148 <- 
org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders() 126 <- 
org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders() 204 <- 
org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders() 178 <- 
org.springframework.core.env.AbstractEnvironment.resolveRequiredPlaceholders() 571 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.resolvePath() 122 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.setConfigLocations() 80 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 137 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 83 <- 
com.bolingcavalry.DemoApplication.main() 14
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: before parse : [CONFIG_PATH]
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: after parse : [CONFIG_PATH]
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper printTrack
信息: start parseStringValue
java.lang.Thread.getStackTrace() 1,559 <- 
org.springframework.util.PropertyPlaceholderHelper.printTrack() 231 <- 
org.springframework.util.PropertyPlaceholderHelper.parseStringValue() 132 <- 
org.springframework.util.PropertyPlaceholderHelper.parseStringValue() 165 <- 
org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders() 126 <- 
org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders() 204 <- 
org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders() 178 <- 
org.springframework.core.env.AbstractEnvironment.resolveRequiredPlaceholders() 571 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.resolvePath() 122 <- 
org.springframework.context.support.AbstractRefreshableConfigApplicationContext.setConfigLocations() 80 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 137 <- 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>() 83 <- 
com.bolingcavalry.DemoApplication.main() 14
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: before parse : [classpath:applicationContext.xml]
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: after parse : [classpath:applicationContext.xml]
七月 07, 2018 7:18:14 下午 org.springframework.util.PropertyPlaceholderHelper parseStringValue
信息: after parse : [classpath:applicationContext.xml]
七月 07, 2018 7:18:14 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@20ad9418: startup date [Sat Jul 07 19:18:14 GMT+08:00 2018]; root of context hierarchy
七月 07, 2018 7:18:14 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
七月 07, 2018 7:18:14 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@20ad9418: startup date [Sat Jul 07 19:18:14 GMT+08:00 2018]; root of context hierarchy
Simple execute method

Process finished with exit code 0
AI 代码解读
  • 上述结果我们看到堆栈信息,能反映出该方法在运行时的调用情况,另外before parseafter parse反映了解析前和解析后的字符串变化,至于为何堆栈会打印多次,那是因为parseStringValue方法自身存在迭代调用的情况,每次都会打印,这从堆栈信息中也能看出来(parseStringValue() 148 );
  • 这个demo的源码可以在github下载,地址和链接信息如下表所示:
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本章源码在springcoredemo文件夹中,如下图红框所示:

这里写图片描述

  • 至此,修改spring-framwork源码的实战就完成了,希望您在学习spring-framwork的时候也能动手修改和构建自己有兴趣的地方,也希望本文能给您一些参考;

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
目录
打赏
0
0
0
0
491
分享
相关文章
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
120 2
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
123 5
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
154 62
基于云效 Windows 构建环境和 Nuget 制品仓库进行 .Net 应用开发
本文将基于云效 Flow 流水线 Windows 构建环境和云效 Packages Nuget 制品仓库手把手教你如何开发并部署一个 .NET 应用,从环境搭建到实战应用发布的详细教程,帮助你掌握 .NET 开发的核心技能。
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
286 12
基于开源框架Spring AI Alibaba快速构建Java应用
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
66 2
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
180 5
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
75 1
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
81 9

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等