Gradle替代Maven成为新的构建工具

588 阅读4分钟

JAVA构建工具

JAVA构建发展历史经历了如下几个阶段。现在使用的最为普遍的是Maven,Jar包中的Pom.xml都是使用maven的方式来进行编译打包。随着Android新起,Gradle慢慢的不仅仅在Android中使用。JAVA,kotlin项目中也可以同步来使用Gradle来进行构建。Kotlin+Gradle来编写后端代码慢慢可以预见的在后端程序中会流行起来。

journey
title build tool
Apache Ant(2000): 1
Maven(2004): 3
Gradle(2012): 5

Maven使用

一直以来,项目中都是使用maven来进行构建,最早由使用ant工具来进行构建。我们使用maven来进行代码编译,打包,发布等一整套完整的JAVA项目的生命周期。

Spring默认构建工具

如果有小伙伴下载过spring源码就会发现spring使用的gradle进行代码构建。需要下载gradle包,就可以打包编译spring源码。alibaba spring就是对源码进行了扩展。

Gradle初试

编译

  • JDK配置
sourceCompatibility = '1.8'
  • maven私服指定
repositories {
   maven {
      allowInsecureProtocol = true
      url 'http://192.168.100.60:18081/repository/maven-snapshots/'
   }
   mavenCentral()
}
  • 引入jar包
dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
   implementation 'org.springframework.boot:spring-boot-starter-web'
   developmentOnly 'org.springframework.boot:spring-boot-devtools'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
   implementation 'org.jetbrains.kotlin:kotlin-reflect'
   implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
   implementation 'p6spy:p6spy:3.8.5'
   implementation 'mysql:mysql-connector-java:8.0.19'
   implementation 'org.springframework.cloud:spring-cloud-starter-alibaba-nacos-config'
   implementation 'org.springframework.cloud:spring-cloud-starter-alibaba-nacos-discovery'
   implementation 'cn.hutool:hutool-all:5.3.5'
   implementation 'com.baomidou:mybatis-plus-boot-starter:3.1.0'
   implementation 'cn.dev33:sa-token-spring-boot-starter:1.30.0'
   implementation 'com.squareup.okhttp3:okhttp:4.8.1'
   implementation('io.minio:minio:8.4.2')
   implementation('org.springframework.cloud:spring-cloud-starter-openfeign')

   annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

}
  • 编码
tasks.withType(JavaCompile) {
    options.encoding= "UTF-8"
}

Spring配置

  • boot版本引入

通过plugin进行引入

plugins {
   id 'org.springframework.boot' version '2.6.4'
   id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
  • bootJar

mainClass支持

mainClassName = 'cn.db.sdk.web.Application'

其他配置

  • lombok引入
// 编译时使用lombok
compileOnly 'org.projectlombok:lombok:1.18.6'
annotationProcessor('org.projectlombok:lombok:1.18.20')

需要添加annotationProcessor,才能在代码启动时不报错。

  • maven发布
task sourcesJar(type: Jar, dependsOn: classes) {
    classifier = 'sources'
    from sourceSets.main.allSource
}
publishing {
    publications {
        maven(MavenPublication) {
            groupId = 'com.wuhanpe.component'
            artifactId = 'xxl-job-spring-boot-starter'
            version = '1.0.0'
            from components.java
            artifact sourcesJar
        }
    }

    repositories {
        maven {
            allowInsecureProtocol = true
            url 'http://192.168.100.60:18081/repository/maven-releases/'
            credentials {
                username = 'admin'
                password = '********'
            }
        }
    }
}

会自动通过gav坐标打包文件然后传到对应的私服上,一般私服都是http,需要开启允许不安全协议。如果需要打包source文件,需要创建task,指定打包的目录。

image.png

通过publishing中的publish进行JAR包远程推送。

  • 编译文件复制

项目中同样集成了前端代码,前端打包成dist文件后,我们可以将前端的代码直接推送到JAVA中的static文件夹中,当我们修改了前端时,前端打包并没有更新,我们可以通过copy步骤将代码复制到编译目录,既可以直接刷新代码,进行调试使用。

task htmlCopy(type: Copy) {

    from 'src/main/resources/static'

    into 'build/resources/main/static'

}

父子项目

gradle中父子项目,相对支持的很好,配置起来也比较简单。

  • 定义子项目中的依赖
subprojects {

    apply plugin: 'java'
    apply plugin: 'maven-publish'

    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    tasks.withType(JavaCompile) {
        options.encoding= "UTF-8"
    }

    tasks.named('compileJava') {
        inputs.files(tasks.named('processResources'))
    }

    dependencies {
        // 封装Starter核心依赖
        implementation('org.springframework.boot:spring-boot-autoconfigure:2.7.2')

        // IDEA编写配置文件有代码提示
        annotationProcessor('org.springframework.boot:spring-boot-configuration-processor:2.7.2')

        // 编译时使用lombok
        compileOnly 'org.projectlombok:lombok:1.18.6'
        annotationProcessor('org.projectlombok:lombok:1.18.20')

        // 日志
        implementation('org.slf4j:slf4j-log4j12:1.7.26')
        implementation('log4j:log4j:1.2.17')
    }

}

看上述代码,非常简洁的配置子项目的依赖,版本,插件,编译编码。框架整体的项目结构层级关系在最外层的setting.gradle中。我们打开如下:

rootProject.name = 'wuhanpe-component'
include 'wuhanpe-component-starter'
include 'wuhanpe-component-starter:xxl-job-spring-boot-starter'
include 'wuhanpe-component-starter:minio-spring-boot-starter'
findProject(':wuhanpe-component-starter:minio-spring-boot-starter')?.name = 'minio-spring-boot-starter'
include 'wuhanpe-component-common'

可以非常简单的使用就可以跑起来我们的项目,项目中使用gradle wrapper,初始需要通过网络下载相应的版本gradle版本的包,后续就可以愉快的开发起来了。

多配置支持

项目中采用groovy版本的gradle,没有使用kotlin的kts。采用多配置的时候,需要自己定义config.groovy文件,使用groovy语法配置多个environment配置。

  • 配置spring环境变量
ext {

    profile = System.properties['spring.profiles.active']

}
  • 读取配置

通过不同环境变量,从config.groovy中读取不同的配置

processResources {

// 获取到配置对象
    def config = new ConfigSlurper(profile).parse(file('config.groovy').toURI().toURL()).toProperties()

    from(sourceSets.main.resources.srcDirs) {

        include 'application.yml','log4j2.xml'
        // 对指定文件进行配置替换,发生在编译时期
        filter(tokens: config, org.apache.tools.ant.filters.ReplaceTokens)

    }

}

总结

经过几个项目采用gradle来使用后,maven的功能已经被完全覆盖了,且提供了较快的编译速度,简洁配置,清晰的父子项目结构。maven中使用xml无法完成进行自定义扩展的痛点,相应的我们可以自定义groovy和kotlin的task。直接进行处理,非常方便快捷。公司后续项目中也会陆续推广都采用gradle进行项目构建来替换掉现有的maven项目构建。