1.spring5.1.x源码编译之旅

449 阅读4分钟

之前由于换电脑,所以把原来编译好的源码上传到了百度网盘里,本以为下载下来就能用,结果并不是。 怎么办呢,只能重新再编译一遍。

本来是打算和写spring源码专栏的初衷放到一起的,想想还是单独在写一篇,如果后续还需要编译自己也能做个参考。

话不多说,直接开干。

下载spring5.1.x源码

下载源码spring5.1.x包并解压。

下载地址:github.com/spring-proj…

image.png

解压zip

image.png

注意:解压以后有2层spring-framework-5.1.x目录,导入idea用最里面的spring-framework-5.1.x目录。

1685413477312.png

安装gradle-5.6.3版本

官网下载链接地址:gradle.org/releases/

image.png

下载完成解压

image.png

新建系统环境变量GRADLE_HOME

image.png

编辑系统环境变量PATH

image.png

新建系统环境变量GRADLE_USER_HOME

配置gradle的仓库地址,此处配置的是默认的仓库地址,用户目录下的.gradle

image.png

校验gradle 是否安装成功: gradle -v

image.png

插一句,jdk用的是1.8.0_181

修改拉取jar包的镜像,换成阿里云。新建文件init.gradle

image.png

init.gradle 内容如下

allprojects{
   repositories {
       def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'
       all { ArtifactRepository repo ->
           if(repo instanceof MavenArtifactRepository){
               def url = repo.url.toString()
               if (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/')) {
                   remove repo
               }
           }
       }

       maven {
            url 'file:///C:/Users/claude.peng/.gradle'
         } 
       maven {
           url REPOSITORY_URL
       }
   }
}

配置Daemon=true,加速gradle的构建。新建文件gradle.properties`

org.gradle.daemon=true

至此gradle安装配置完成。

导入spring5.1.x到idea

首先关闭所有打开的项目。

image.png

选择Import Project

image.png

选择我们下载的源码的目录:E:\study\spring-framework-5.1.x\spring-framework-5.1.x

image.png

导入会自动下载依赖然后提示报错。

image.png

配置idea中的gradle。

image.png

注意jdk也要配置一下。

在build.gradle中增加repositories部分的配置,一共有2处。

buildscript {
   repositories {
      gradlePluginPortal()
      mavenLocal()
      maven { url "https://repo.spring.io/plugins-release" }
      maven { url "https://maven.aliyun.com/repository/spring" }
      maven { url "https://maven.aliyun.com/repository/public" }
   }
   dependencies {
      classpath("io.spring.gradle:propdeps-plugin:0.0.9.RELEASE")
      classpath("org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16")
   }
}
repositories {
   mavenCentral()
   maven { url "https://repo.spring.io/libs-spring-framework-build" }
   maven { url "https://maven.aliyun.com/repository/spring" }
   maven { url "https://maven.aliyun.com/repository/public" }
}

修改完毕,重新刷新导入。

image.png

依赖下载完成

image.png

首先编译spring-core,所谓的编译也就是执行项目下的Tasks--other--compileTestJava,双击即可。

image.png

出现以下提示代表编译成功完成。

image.png

由于项目之间有依赖关系,所以编译顺序要严格按照下面的顺序来。

编译顺序:core-oxm-context-beans-aspect-aop-tx

编译完成后就可以创建自己的module。

image.png

由于我们用的gradle,因此创建module一定要选择gradle

image.png

下一步

image.png

完成即可

修改source-code-study中的依赖,配置如下

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile(project(":spring-beans"))
    compile(project(":spring-core"))
    compile(project(":spring-context"))
    compile(project(":spring-aop"))
    compile(project(":spring-aspects"))
    compile(project(":spring-tx"))
}

编写启动类测试

package beanDefinition;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
//包扫描
@ComponentScan("beanDefinition")
//使用xml文件启动
//@ImportResource("applicationContext.xml")
public class Config {
   public Config() {
      System.out.println("------------------------Config实例化了");
   }
}
package beanDefinition;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringTest {
    public static void main(String[] args) throws InterruptedException {
        start1();
    }
    
     public static void start1() {
      //其中Config.class可以指定为
        //包扫描启动:@ComponentScan("tyrant")
        //使用xml文件启动:@ImportResource("applicationContext.xml")
      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
       context.scan("beanDefinition");
       //注册配置类
       System.out.println("context.register(Config.class);前");
      context.register(Config.class);
       System.out.println("context.register(Config.class);后");
       GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
       beanDefinition.setBeanClassName("beanDefinition.User");
       //设置beanDefinition的属性值
       beanDefinition.setAttribute("name","源码之路");
       //设置对象的属性值
       beanDefinition.getPropertyValues().addPropertyValue("name","排放量");
       //将beanDefinition注册到spring容器中
       context.registerBeanDefinition("userService",beanDefinition);

      context.refresh();
       //加载或者刷新当前的配置信息
       User userService = (User) context.getBean("userService");
       System.out.println("属性值" + userService.getName());


       BeanDefinition userServiceBeanDefinition =
             context.getBeanDefinition("userService");

       System.out.println("——————InterService的附加属性如下:");
       System.out.println("父类"+userServiceBeanDefinition.getParentName());
       System.out.println("描述"+userServiceBeanDefinition.getDescription());
       System.out.println("InterService在spring的名称"+     userServiceBeanDefinition.getBeanClassName());
       System.out.println("实例范围"+userServiceBeanDefinition.getScope());
       System.out.println("是否是懒加载"+userServiceBeanDefinition.isLazyInit());
       System.out.println("是否是抽象类"+userServiceBeanDefinition.isAbstract());
       System.out.println("hasAttribute"+userServiceBeanDefinition.hasAttribute("name"));
       System.out.println("——————等等等等,读者自行编写");


       BeanDefinition user =
             context.getBeanDefinition("user");
       System.out.println(user.getClass().getSimpleName());

       BeanDefinition config =
             context.getBeanDefinition("config");
       System.out.println(config.getClass().getSimpleName());

    }
   public static void start2() {
      //其中Config.class可以指定为
        //包扫描启动:@ComponentScan("tyrant")
        //使用xml文件启动:@ImportResource("applicationContext.xml") 
      AnnotationConfigApplicationContext context = new         
                                       AnnotationConfigApplicationContext(Config.class);
      //加载或者刷新当前的配置信息
      context.refresh();
   }
}
package beanDefinition;

import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Component;

@Component
@Description("业务类")
public class User {
    private int age =31;
    private String name;

   public int getAge() {
      return age;
   }

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

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

运行TestMethod之前,我们需要设置kotlin Compiler,不设置的话,会出现以下提示而且运行很慢

image.png

Warning:Kotlin: Language version 1.1 is deprecated and its support will be removed in a future version of Kotlin

运行SpringTest看看是否能够正确打印信息。如果能打印但是乱码。

image.png

增加以下配置

在idea中vm options最后一行加入 -Dfile.encoding=UTF-8

image.png

附录

1.gradle的仓库下载的依赖的目录 C:\Users\claude.peng\.gradle\caches\modules-2\files-2.1

当有依赖下载不下来我们可以在网上下载下来放在本地仓库。

2.阿里云云效 Maven 中央代理仓库,我们可以在这里下载找不到的依赖,自己创建目录放到本地仓库。

地址: developer.aliyun.com/mvn/search

3.编译源码的过程中可能还会遇到其他的问题,欢迎交流。笔者跟着自己写的教程重新编译了一次,没有任何问题,完美,收工~