第一章:Gradle 日志信息
1.1 概述
- 在进行项目开发的过程之中,所有重要的数据内容一般都需要通过日志的形式进行输出,既然 Gradle 是以 Groovy 语言编写的可编程的构建工具,那么在进行每一个任务处理的时候也可以进行日志的配置,同时在 Gradle 内部直接提供有各种日志的组件。
1.2 日志输出
- 所有的日志都是有日志等级的: | 等级 | 描述 | | —- | —- | | ERROR | 错误消息 | | QUIET | 重要消息信息 | | WARN | 警告信息 | | LIFECYCLE | 进度消息信息 | | INFO | 信息消息 | | DEBUG | 调试信息 |
- 使用不同的日志等级实现日志信息的打印,修改 build.gradle 文件:
task helloTask {doFirst {logger.log(LogLevel.ERROR,'【ERROR】这是一个 ERROR 级别日志信息')logger.quiet('【QUIET】这是一个 QUIET 级别日志信息')logger.info('【INFO】这是一个 INFO 级别日志信息')logger.log(LogLevel.WARN,'【WARN】这是一个 WARN 级别日志信息')logger.debug('【DEBUG】这是一个 DEBUG 级别日志信息')logger.lifecycle('【LIFE_CYCLE】这是一个 LIFE_CYCLE 级别日志信息')}}
- 程序执行命令:
gradle helloTask
- 程序执行结果:
14:20:01: 正在执行 'helloTask'…> Task :helloTask【QUIET】这是一个 QUIET 级别日志信息【WARN】这是一个 WARN 级别日志信息【LIFE_CYCLE】这是一个 LIFE_CYCLE 级别日志信息BUILD SUCCESSFUL in 58ms1 actionable task: 1 executed【ERROR】这是一个 ERROR 级别日志信息14:20:02: 执行完成 'helloTask'。
- 这个时候日志的确是提供了,但是默认情况下执行的任务并不会触发所有的日志输出操作,如果要想获得指定类型的日志信息,那么就需要在任务执行的时候进行配置了。
1.3 日志控制
- 对于不同级别的日志,需要通过任务执行的时候配置不同的日志等级才可以实现输出,对于日志等级有如下的几个配置项: | 选项 | 输出日志级别 | | —- | —- | | 没有日志选项 | LIFECYCLE 或更高 | | -q 或 —quiet | QUIET 或更高 | | -w 或 —warn | WARN 或更高 | | -i 或 —info | INFO 或更高 | | -d 或 —debug | DEBUG 或更高 |
对于所有的日志,肯定要设置输出级别才能准确获取相应的日志信息。
示例:使用 debug 日志范围
- 程序执行命令:
gradle helloTask --debug
- 程序执行结果:
2021-12-27T14:26:58.616+0800 [QUIET] [org.gradle.api.Task] 【QUIET】这是一个 QUIET 级别日志信息2021-12-27T14:26:58.616+0800 [INFO] [org.gradle.api.Task] 【INFO】这是一个 INFO 级别日志信息2021-12-27T14:26:58.616+0800 [WARN] [org.gradle.api.Task] 【WARN】这是一个 WARN 级别日志信息2021-12-27T14:26:58.616+0800 [DEBUG] [org.gradle.api.Task] 【DEBUG】这是一个 DEBUG 级别日志信息2021-12-27T14:26:58.616+0800 [LIFECYCLE] [org.gradle.api.Task] 【LIFE_CYCLE】这是一个 LIFE_CYCLE 级别日志信息
第二章:Gradle 项目源代码打包
2.1 概述
- 对于任何一个项目来说,除了需要将核心的功能程序(编译后的)进行打包处理之外,实际上还需要考虑的就是开源项目中的源代码的打包操作,对于源代码的打包操作,需要单独配置有一个 Gradle 任务才可以实现。
2.2 源代码任务
- 如果要想进行源代码的打包,那么需要定义个新的任务,但是这个任务需要继承一个 jar 已有的任务,修改 build.gradle 文件:
// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar) { // 定义一个源代码的打包任务archiveBaseName.set 'gradle-01' // 生成 jar 文件的名称archiveVersion.set '1.0.0' // 定义项目打包版本archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径exclude(['**/*.xml', '**/*.properties']) // 排除配置文件,可选destinationDirectory.file("$buildDir/source-jar") // 目标存储路径manifest {attributes 'packageName': 'com.github.fairy.era','Built-By': '许大仙','Built-date': new Date().format('yyyy-MM-dd HH:mm:ss'),'Manifest-Version': archiveVersion}}
- 完整的 build.gradle 文件:
plugins {id 'java' // 配置的是一个 Java 插件(Java 项目)id 'java-library'}ext {jdkVersion = JavaVersion.VERSION_1_8 // 传统的 JDK 版本都是需要自己编写字符串的,而 Gradle 中提供了这样的操作}apply from: 'dependencies.gradle' // 引入所有的依赖文件configurations { // 进行依赖的配置implementation {canBeConsumed = truecanBeResolved = true}}group 'com.github.fairy.era' // 组织名称version '1.0' // 项目版本// 定义一个公共的变量描述当前使用的 JDK 版本sourceCompatibility = jdkVersiontargetCompatibility = jdkVersionrepositories { // 仓库配置mavenCentral()}dependencies { // 依赖管理// compile gradleApi()/* junit 5 */testImplementation( // 如果有多个依赖,使用 , 隔开libraries.'junit-jupiter')/* druid */implementation( // 如果有多个依赖,使用 , 隔开libraries.'druid')}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}def mainClassName = 'com.github.fairy.era.GradleMain' // 程序的主类名称jar {archivesBaseName = 'gradle' // 生成的 jar 文件名称,如果不写此名称则使用项目名称manifestContentCharset = 'UTF-8' // 设置整个文件的编码metadataCharset = 'UTF-8' // 元数据设置编码manifest {attributes 'Manifest-Version': getArchiveVersion().getOrNull(), // 程序版本号'Main-Class': "${mainClassName}",// 程序主类名称'Implementation-Title': 'hello-gradle',// 程序主类名称'Implementation-Version': archiveVersion // 版本编号}into('lib') { // 将程序锁需要的第三方组件包配置到 lib 目录之中from configurations.compileClasspath}}test { // 进行测试任务的配置useJUnitPlatform() // 使用 Junit 平台}sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config']}}}// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar) { // 定义一个源代码的打包任务archiveBaseName.set 'gradle-01' // 生成 jar 文件的名称archiveVersion.set '1.0.0' // 定义项目打包版本archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径exclude(['**/*.xml', '**/*.properties']) // 排除配置文件,可选destinationDirectory.file("$buildDir/source-jar") // 目标存储路径manifest {attributes 'packageName': 'com.github.fairy.era','Built-By': '许大仙','Built-date': new Date().format('yyyy-MM-dd HH:mm:ss'),'Manifest-Version': archiveVersion}}
2.3 打包处理
- 既然此时已经明确的定义一个打包任务,那么就可以直接通过此任务的执行来实现源代码包的生成。
- 程序执行命令:
gradle sourceJar
- 程序执行结果:

2.4 打包时机
- 当前的操作虽然可以编写任务实现源代码的打包处理操作,但是有一个问题:通常是在程序最终编译的时候才进行打包处理,如果按照以上的方式单独定义一个新的任务,则意味着需要在整个程序之中单独配置任务,能够将这些任务合并在一起?
- 修改 build.gradle 文件:
task sourceJar(type: Jar,dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}
2.5 命令整合
- 以上的任务仅仅是对已有的任务做了一个扩展,但是需要注意的是,毕竟现在的需求是将整个源代码的操作放在 build 之中,所以还需要进行一个额外的配置,修改 build.gradle 文件:
// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar,dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}artifacts { // 最终的打包操作任务archives sourceJar}
- 完整的 build.gradle 文件:
plugins {id 'java' // 配置的是一个 Java 插件(Java 项目)id 'java-library'}ext {jdkVersion = JavaVersion.VERSION_1_8 // 传统的 JDK 版本都是需要自己编写字符串的,而 Gradle 中提供了这样的操作}apply from: 'dependencies.gradle' // 引入所有的依赖文件configurations { // 进行依赖的配置implementation {canBeConsumed = truecanBeResolved = true}}group 'com.github.fairy.era' // 组织名称version '1.0' // 项目版本// 定义一个公共的变量描述当前使用的 JDK 版本sourceCompatibility = jdkVersiontargetCompatibility = jdkVersionrepositories { // 仓库配置mavenCentral()}dependencies { // 依赖管理// compile gradleApi()/* junit 5 */testImplementation( // 如果有多个依赖,使用 , 隔开libraries.'junit-jupiter')/* druid */implementation( // 如果有多个依赖,使用 , 隔开libraries.'druid')}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}def mainClassName = 'com.github.fairy.era.GradleMain' // 程序的主类名称jar {archivesBaseName = 'gradle' // 生成的 jar 文件名称,如果不写此名称则使用项目名称manifestContentCharset = 'UTF-8' // 设置整个文件的编码metadataCharset = 'UTF-8' // 元数据设置编码manifest {attributes 'Manifest-Version': getArchiveVersion().getOrNull(), // 程序版本号'Main-Class': "${mainClassName}",// 程序主类名称'Implementation-Title': 'hello-gradle',// 程序主类名称'Implementation-Version': archiveVersion // 版本编号}into('lib') { // 将程序锁需要的第三方组件包配置到 lib 目录之中from configurations.compileClasspath}}test { // 进行测试任务的配置useJUnitPlatform() // 使用 Junit 平台}sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config']}}}// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar,dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}artifacts { // 最终的打包操作任务archives sourceJar}
- 程序执行命令:
gradle clean build -x test
- 程序执行结果:

第三章:Gradle 打包 javadoc
3.1 概述
- 一个完整的项目在进行打包的时候一个会有三个
*.jar文件:主程序(gradle-1.0.jar)、源代码(gradle-1.0-sources.jar)和文档(gradle-1.0-javadoc.jar),如果要生成程序的 javadoc 文档,那么首先一定需要在项目中追加相应的文档说明,同时还需要在 build.gradle 文件中定义有相关的任务处理。
3.2 文档注释
- 略(一般项目中都需要写文档注释的)。
3.3 Gradle 的任务配置
- 如果要想生成 javadoc,则需要配置有相关的任务,Gradle 里面已经有了这样的内置任务,我们只需要对 javadoc 任务做一个继承处理即可,修改 build.gradle 文件:
task javaDocTask(type: Javadoc){source sourceSets.main.allJava // 定义所有的 Java 源代码的路径}tasks.withType(Javadoc){ // 文档生成一定要有乱码处理options.encoding = "UTF-8"}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}
- 程序执行命令:
gradle javaDocTask
- 程序执行结果:

- 当命令执行完成之后,会自动在 build/docs/javadoc 目录下生成所有的 JavaDoc 文档。
3.4 打包 JavaDoc
- 最终在进行项目发布的时候,肯定要生成 javadoc 的 jar 文件,此时就需要定义一个打包任务,修改 build.gradle 文件:
task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包archiveClassifier.set 'javadoc' // 文件的分类from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径}
3.5 命令整合
- javadoc 的生成也应该在整个压缩结构文件生成的同时进行创建,修改 build.gradle 文件:
task javaDocTask(type: Javadoc) {source sourceSets.main.allJava // 定义所有的 Java 源代码的路径}tasks.withType(Javadoc) { // 文档生成一定要有乱码处理options.encoding = "UTF-8"}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包archiveClassifier.set 'javadoc' // 文件的分类from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径}artifacts { // 最终的打包操作任务archives sourceJararchives javaDocJar}
- 完整的 build.gradle 文件:
plugins {id 'java' // 配置的是一个 Java 插件(Java 项目)id 'java-library'}ext {jdkVersion = JavaVersion.VERSION_1_8 // 传统的 JDK 版本都是需要自己编写字符串的,而 Gradle 中提供了这样的操作}apply from: 'dependencies.gradle' // 引入所有的依赖文件configurations { // 进行依赖的配置implementation {canBeConsumed = truecanBeResolved = true}}group 'com.github.fairy.era' // 组织名称version '1.0' // 项目版本// 定义一个公共的变量描述当前使用的 JDK 版本sourceCompatibility = jdkVersiontargetCompatibility = jdkVersionrepositories { // 仓库配置mavenCentral()}dependencies { // 依赖管理// compile gradleApi()/* junit 5 */testImplementation( // 如果有多个依赖,使用 , 隔开libraries.'junit-jupiter')/* druid */implementation( // 如果有多个依赖,使用 , 隔开libraries.'druid')}def mainClassName = 'com.github.fairy.era.GradleMain' // 程序的主类名称jar {archivesBaseName = 'gradle' // 生成的 jar 文件名称,如果不写此名称则使用项目名称manifestContentCharset = 'UTF-8' // 设置整个文件的编码metadataCharset = 'UTF-8' // 元数据设置编码manifest {attributes 'Manifest-Version': getArchiveVersion().getOrNull(), // 程序版本号'Main-Class': "${mainClassName}",// 程序主类名称'Implementation-Title': 'hello-gradle',// 程序主类名称'Implementation-Version': archiveVersion // 版本编号}into('lib') { // 将程序锁需要的第三方组件包配置到 lib 目录之中from configurations.compileClasspath}}test { // 进行测试任务的配置useJUnitPlatform() // 使用 Junit 平台}sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config']}}}// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar, dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}task javaDocTask(type: Javadoc) {source sourceSets.main.allJava // 定义所有的 Java 源代码的路径}tasks.withType(Javadoc) { // 文档生成一定要有乱码处理options.encoding = "UTF-8"}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包archiveClassifier.set 'javadoc' // 文件的分类from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径}artifacts { // 最终的打包操作任务archives sourceJararchives javaDocJar}
- 程序执行命令:
gradle clean build -x test
- 程序执行结果:

第四章:Gradle 程序测试控制
4.1 概述
- 在 Gradle 项目中所有的代码都要有相应的测试用例存在,但是如果说在一些环境下测试用例可能无法正常执行,那么面对这样的情况,就需要每次在编译打包的时候都使用
-x test来跳过测试。 - 在 Maven 里面有一种插件,通过配置可以避免执行测试的代码,但是在 Gradle 中并没有这样的插件,如果要想实现测试代码的跳过,就需要手工编写程序。
4.2 错误测试
- 为了更好的说明问题,首先编写一个错误的测试代码:
package com.github.era.fairy.service;import com.github.fairy.era.service.IMessageService;import com.github.fairy.era.service.impl.MessageServiceImpl;import org.junit.jupiter.api.Assertions;import org.junit.jupiter.api.Test;/*** @author 许大仙* @version 1.0* @since 2021-12-21 08:43*/public class MessageServiceTest {@Testpublic void test() {IMessageService messageService = new MessageServiceImpl();Assertions.assertEquals("你好啊", messageService.echo("Gradle"));}}
- 程序执行结果:
> Task :compileJava UP-TO-DATE> Task :processResources UP-TO-DATE> Task :classes UP-TO-DATE> Task :compileTestJava> Task :processTestResources NO-SOURCE> Task :testClasses> Task :test FAILEDexpected: <你好啊> but was: <hello Gradle>预期:你好啊实际:hello Gradle<点击以查看差异>org.opentest4j.AssertionFailedError: expected: <你好啊> but was: <hello Gradle>at com.github.era.fairy.service.MessageServiceTest.test(MessageServiceTest.java:18)at java.util.ArrayList.forEach(ArrayList.java:1249)at java.util.ArrayList.forEach(ArrayList.java:1249)MessageServiceTest > test() FAILEDorg.opentest4j.AssertionFailedError at MessageServiceTest.java:181 test completed, 1 failedFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':test'.> There were failing tests. See the report at: file:///D:/project/gradle-01/build/reports/tests/test/index.html* 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.* Get more help at https://help.gradle.orgBUILD FAILED in 1s4 actionable tasks: 2 executed, 2 up-to-date
4.3 代码影响
- 这样的程序代码在进行编译打包时候,一定会带来无法正常运行的问题。
- 程序执行命令:
gradle clean build
- 程序执行结果:
Execution failed for task ':test'.> There were failing tests. See the report at: file:///D:/project/gradle-01/build/reports/tests/test/index.html* 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.
- 传统的解决方式就是使用
-x test命令参数来进行控制,但是太麻烦了。
4.4 测试的控制任务
- 如果要想解决当前测试代码对整个程序的影响,可以考虑做一个开关,修改 build.gradle 文件:
gradle.taskGraph.whenReady { // 在所有的操作准备好之后触发tasks.each { task ->if (task.name.contains('test')) { // 如果发现有 test 任务,就跳过task.enabled = false // 当前任务不执行}}}
- 当项目中配置了这样的处理之后,实际上最终所有的程序的测试都会失效,因为只要发现是测试的指令,就会关闭任务处理。
第五章:Gradle 多环境配置管理
5.1 概述
- 一个项目如果要想正常使用,则一般会经历:开发环境、测试环境和线上环境,不同的环境对于一些程序的配置信息也有所不同,那么这样的操作都可以通过 profile 来进行配置。
- 按照正常的开发逻辑,应该将所有的网络服务器的信息,保存在不同的 profile 文件里面,例如:现在假设在 src/main 目录下创建一个 profiles 公共目录。
.|-- LICENSE|-- build.gradle|-- gradle| `-- wrapper| |-- gradle-wrapper.jar| `-- gradle-wrapper.properties|-- gradlew|-- gradlew.bat|-- settings.gradle`-- src|-- main| |-- config| | |-- database.properties| | |-- dubbo.properties| | `-- redis.properties| |-- java| |-- profiles # 公共目录| | |-- dev # 开发环境| | | `-- config| | | `-- database.properties| | |-- prod # 生产环境| | | `-- config| | | `-- database.properties| | `-- test # 测试环境| | `-- config| | `-- database.properties| `-- resources`-- test|-- java`-- resources
5.2 定义 profile
- 以上的三个不同的属性文件在项目中的所有 key 的内容是相同的,不同的仅仅是 key 对应的 value ,在程序执行的时候就可以根据不同的环境实现配置的切换。
- src/main/profiles/dev/config/database.properties:
druid.database.name=gradle-devdruid.database.username=gradle-dev
- src/main/profiles/test/config/database.properties:
druid.database.name=gradle-proddruid.database.username=gradle-prod
- src/main/profiles/prod/config/database.properties:
druid.database.name=gradle-testdruid.database.username=gradle-test
5.3 Gradle 配置
- 如果要想让当前的这个 profile 路径生效,则一定要修改 build.gradle 配置文件,在这个配置文件里面定义源代码的访问路径,但是这个路径需要注意的是,里面的 profile 名称是需要动态变更的。
| 环境 | profile 路径 |
| —- | —- |
| 开发环境 | src/main/profiles/
dev
/config/database.properties | | 测试环境 | src/main/profiles/test
/config/database.properties | | 生产环境 | src/main/profiles/prod
/config/database.properties |
- 修改 build.gradle 文件,获取 env 环境属性:
def env = System.getProperty("env")?:'dev' // 获取 env 的环境属性
- 对于当前可以接受的 env 环境属性,实际上就属于最终的
src/main/profiles/xxx的动态内容,最终所需要的 profile 的具体内容就是由这个变量决定的,那么修改 build.gradle 文件:
sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config', "src/main/profiles/${env}"]}}}
- 完整的 build.gradle 文件:
plugins {id 'java' // 配置的是一个 Java 插件(Java 项目)id 'java-library'}ext {jdkVersion = JavaVersion.VERSION_1_8 // 传统的 JDK 版本都是需要自己编写字符串的,而 Gradle 中提供了这样的操作}apply from: 'dependencies.gradle' // 引入所有的依赖文件configurations { // 进行依赖的配置implementation {canBeConsumed = truecanBeResolved = true}}group 'com.github.fairy.era' // 组织名称version '1.0' // 项目版本// 定义一个公共的变量描述当前使用的 JDK 版本sourceCompatibility = jdkVersiontargetCompatibility = jdkVersiondef env = System.getProperty("env")?:'dev' // 获取 env 的环境属性repositories { // 仓库配置mavenCentral()}dependencies { // 依赖管理// compile gradleApi()/* junit 5 */testImplementation( // 如果有多个依赖,使用 , 隔开libraries.'junit-jupiter')/* druid */implementation( // 如果有多个依赖,使用 , 隔开libraries.'druid')}def mainClassName = 'com.github.fairy.era.GradleMain' // 程序的主类名称jar {archivesBaseName = 'gradle' // 生成的 jar 文件名称,如果不写此名称则使用项目名称manifestContentCharset = 'UTF-8' // 设置整个文件的编码metadataCharset = 'UTF-8' // 元数据设置编码manifest {attributes 'Manifest-Version': getArchiveVersion().getOrNull(), // 程序版本号'Main-Class': "${mainClassName}",// 程序主类名称'Implementation-Title': 'hello-gradle',// 程序主类名称'Implementation-Version': archiveVersion // 版本编号}into('lib') { // 将程序锁需要的第三方组件包配置到 lib 目录之中from configurations.compileClasspath}}test { // 进行测试任务的配置useJUnitPlatform() // 使用 Junit 平台}sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config', "src/main/profiles/${env}"]}}}gradle.taskGraph.whenReady { // 在所有的操作准备好之后触发tasks.each { task ->if (task.name.contains('test')) { // 如果发现有 test 任务,就跳过task.enabled = true // 当前任务不执行}}}// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar, dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}task javaDocTask(type: Javadoc) {source sourceSets.main.allJava // 定义所有的 Java 源代码的路径}tasks.withType(Javadoc) { // 文档生成一定要有乱码处理options.encoding = "UTF-8"}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包archiveClassifier.set 'javadoc' // 文件的分类from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径}artifacts { // 最终的打包操作任务archives sourceJararchives javaDocJar}
5.4 打包处理
- 此时给出的是一个 Java 环境属性,所以环境属性可以采用
-D属性名称 = 内容的形式来进行处理,而后要进行程序的打包配置。 - 开发环境打包命令(任选其一即可):
gradle clean build
gradle clean build -Denv=dev
- 测试环境打包命令:
gradle clean build -Denv=test
- 生产环境打包命令:
gradle clean build -Denv=prod
5.5 依赖配置
- 长期以来如果使用 Maven 都会发现有一个核心问题:依赖库的版本永远都是需要固定配置,即使有不同的 profile,依赖库也是无法变更的;但是在 Gradle 里面,将这个问题解决了,在之前为了进行依赖的统一管理,提供有一个 dependencies.gradle 的配置文件,那么如果要想实现不同版本的切换,就可以通过这样的文件形式来进行控制。
- 下面建立
dependencies-xxx.gradle的配置文件,其中xxx代表 dev、test 和 prod。 - dependencies-dev.gradle 的内容如下:
// 定义所有要使用的版本号ext.versions = [junitJupiterVersion: '5.8.0',druidVersion : '1.2.6']// 定义所有的依赖库ext.libraries = [/* junit 5 */'junit-jupiter': "org.junit.jupiter:junit-jupiter:${versions.junitJupiterVersion}",/* druid */druid : "com.alibaba:druid:${versions.druidVersion}"]
- dependencies-test .gradle 的内容如下:
// 定义所有要使用的版本号ext.versions = [junitJupiterVersion: '5.8.1',druidVersion : '1.2.7']// 定义所有的依赖库ext.libraries = [/* junit 5 */'junit-jupiter': "org.junit.jupiter:junit-jupiter:${versions.junitJupiterVersion}",/* druid */druid : "com.alibaba:druid:${versions.druidVersion}"]
- dependencies-prod.gradle 的内容如下:
// 定义所有要使用的版本号ext.versions = [junitJupiterVersion: '5.8.2',druidVersion : '1.2.8']// 定义所有的依赖库ext.libraries = [/* junit 5 */'junit-jupiter': "org.junit.jupiter:junit-jupiter:${versions.junitJupiterVersion}",/* druid */druid : "com.alibaba:druid:${versions.druidVersion}"]

5.6 动态导入
- 修改 build.gradle 文件,针对于依赖配置库进行动态配置:
def env = System.getProperty("env")?:'dev' // 获取 env 的环境属性apply from: "dependencies-${env}.gradle" // 引入所有的依赖文件
- 开发环境打包命令:
gradle clean build
gradle clean build -Denv=dev
- 测试环境打包命令:
gradle clean build -Denv=test
- 生产环境打包命令:
gradle clean build -Denv=prod
- 完成的 build.gradle 文件:
plugins {id 'java' // 配置的是一个 Java 插件(Java 项目)id 'java-library'}ext {jdkVersion = JavaVersion.VERSION_1_8 // 传统的 JDK 版本都是需要自己编写字符串的,而 Gradle 中提供了这样的操作}def env = System.getProperty("env")?:'dev' // 获取 env 的环境属性apply from: "dependencies-${env}.gradle" // 引入所有的依赖文件configurations { // 进行依赖的配置implementation {canBeConsumed = truecanBeResolved = true}}group 'com.github.fairy.era' // 组织名称version '1.0' // 项目版本// 定义一个公共的变量描述当前使用的 JDK 版本sourceCompatibility = jdkVersiontargetCompatibility = jdkVersionrepositories { // 仓库配置mavenCentral()}dependencies { // 依赖管理// compile gradleApi()/* junit 5 */testImplementation( // 如果有多个依赖,使用 , 隔开libraries.'junit-jupiter')/* druid */implementation( // 如果有多个依赖,使用 , 隔开libraries.'druid')}def mainClassName = 'com.github.fairy.era.GradleMain' // 程序的主类名称jar {archivesBaseName = 'gradle' // 生成的 jar 文件名称,如果不写此名称则使用项目名称manifestContentCharset = 'UTF-8' // 设置整个文件的编码metadataCharset = 'UTF-8' // 元数据设置编码manifest {attributes 'Manifest-Version': getArchiveVersion().getOrNull(), // 程序版本号'Main-Class': "${mainClassName}",// 程序主类名称'Implementation-Title': 'hello-gradle',// 程序主类名称'Implementation-Version': archiveVersion // 版本编号}into('lib') { // 将程序锁需要的第三方组件包配置到 lib 目录之中from configurations.compileClasspath}}test { // 进行测试任务的配置useJUnitPlatform() // 使用 Junit 平台}sourceSets { // 建立源代码的目录集合main {java {srcDirs = ['src/main/java']}resources {srcDirs = ['src/main/resources', 'src/main/config', "src/main/profiles/${env}"]}}}gradle.taskGraph.whenReady { // 在所有的操作准备好之后触发tasks.each { task ->if (task.name.contains('test')) { // 如果发现有 test 任务,就跳过task.enabled = true // 当前任务不执行}}}// 最终生成的 jar 文件名称:baseName-version-classifier.extensiontask sourceJar(type: Jar, dependsOn: classes) { // 定义一个源代码的打包任务,并依赖于 classes 这种 Gradle 内置的任务archiveClassifier.set 'sources' // 文件的分类from sourceSets.main.allSource // 所有源代码的读取路径}task javaDocTask(type: Javadoc) {source sourceSets.main.allJava // 定义所有的 Java 源代码的路径}tasks.withType(Javadoc) { // 文档生成一定要有乱码处理options.encoding = "UTF-8"}tasks.withType(JavaCompile) { // 针对程序编译的任务进行配置options.encoding = "UTF-8"}task javaDocJar(type: Jar, dependsOn: javaDocTask) { // 先生成 javadoc,才可以打包archiveClassifier.set 'javadoc' // 文件的分类from javaDocTask.destinationDir // 通过 javaDocTask 任务中找到目标路径}artifacts { // 最终的打包操作任务archives sourceJararchives javaDocJar}
