1. 概述

在本文中,我们将探讨 Gradle Java 项目中的不同配置文件,并了解实际构建过程的细节。

如果您需要关于 Gradle 的基础介绍,可以查看 Gradle 简介

2. build.gradle

假设我们通过运行 gradle init --type java-application 命令创建一个全新的 Java 项目。这将生成一个具有以下目录和文件结构的新项目:

build.gradle
gradle    
    wrapper
        gradle-wrapper.jar
        gradle-wrapper.properties
gradlew
gradlew.bat
settings.gradle
src
    main
        java  
            App.java
    test      
        java
            AppTest.java

我们可以将 build.gradle 文件视为项目的核心配置文件。在本示例中,该文件的内容如下所示:

plugins {
    id 'java'
    id 'application'
}
 
mainClassName = 'App'
 
dependencies {
    compile 'com.google.guava:guava:23.0'
 
    testCompile 'junit:junit:4.12'
}
 
repositories {
    jcenter()
}

该文件由 Groovy 代码组成,更准确地说,是由用于描述构建过程的基于 Groovy 的 DSL(Domain Specific Language,领域特定语言)构成。我们可以在此处定义依赖关系,并配置用于依赖解析的仓库(例如 Maven 仓库)。

Gradle 的基本构建块是项目(Project)任务(Task)。在这种情况下,由于应用了 Java 插件,因此隐式定义了构建 Java 项目所需的所有必要任务。其中一些任务包括 assemblecheckbuildjarjavadocclean 等。

这些任务的配置方式描述了 Java 项目的依赖关系图。这意味着通常只需执行 build 任务,Gradle(配合 Java 插件)便会确保所有必需的任务均已按顺序执行。

如果我们需要其他专用任务(例如构建 Docker 镜像),也可以将其定义在 build.gradle 文件中。任务的最简单定义如下所示:

task hello {
    doLast {
        println 'Hello Baeldung!'
    }
}

我们可以通过将任务名作为 Gradle CLI 的参数来运行该任务,如下所示:

$ gradle -q hello
Hello Baeldung!

虽然这没有实际业务用途,但它成功打印了"Hello Baeldung!"。

如果是多项目构建(Multi-project Build),我们可能会有多个不同的 build.gradle 文件,每个子项目对应一个。

build.gradle 文件针对具体的项目实例执行,每个子项目都会创建一个项目实例。上述可以在 build.gradle 文件中定义的任务,作为 Task 对象集合的一部分驻留在 Project 实例中。任务本身由多个操作(Action)组成(作为有序列表)。

在前面的示例中,我们添加了一个 Groovy 闭包来打印"Hello Baeldung!"。通过在 hello 任务对象上调用 doLast(Closure action),可以将此操作添加到列表的末尾。在任务执行期间,Gradle 通过调用 Action.execute(T) 方法按顺序执行其每个 Action。

3. settings.gradle

Gradle 还会生成 settings.gradle 文件:

rootProject.name = 'gradle-example'

settings.gradle 文件同样是一个 Groovy 脚本。

build.gradle 文件相比,每个 Gradle 构建仅执行一个 settings.gradle 文件。我们可以使用它来定义多项目构建中的项目结构。

此外,我们还可以将代码注册为构建不同生命周期挂钩(Lifecycle Hooks)的一部分。

该框架要求在多项目构建中必须存在 settings.gradle,而对于单项目构建则是可选的。

在创建构建的 Settings 实例之后,通过对该文件执行并对其进行配置来使用该文件。这意味着我们要在 settings.gradle 文件中定义子项目,如下所示:

include 'foo', 'bar'

创建构建时,Gradle 会在 Settings 实例上调用 void include(String…projectPaths) 方法。

4. gradle.properties

Gradle 默认情况下不会创建 gradle.properties 文件。它可以位于不同的位置,例如项目根目录中、GRADLE_USER_HOME 内,或由 -Dgradle.user.home 命令行标志指定的位置中。

该文件由键值对组成。我们可以使用它来配置框架本身的行为,这是使用命令行标志进行配置的替代方法。

可能的键示例包括:

  • org.gradle.caching=(true,false)
  • org.gradle.daemon=(true,false)
  • org.gradle.parallel=(true,false)
  • org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)

另外,您可以使用此文件将属性直接添加到 Project 对象,例如具有名称空间的属性:org.gradle.project.property_to_set

另一个用例是指定 JVM 参数,如下所示:

org.gradle.jvmargs=-Xmx2g -XX:MaxPermSize=256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

请注意,这需要启动 JVM 进程来解析 gradle.properties 文件。这意味着这些 JVM 参数仅影响单独启动的 JVM 进程。

5. 构建流程简述

假设我们不将其作为守护进程(Daemon)运行,我们可以将 Gradle 构建的一般生命周期总结如下:

  1. 它作为新的 JVM 进程启动。
  2. 它解析 gradle.properties 文件并相应地配置 Gradle。
  3. 接下来,它为构建创建一个 Settings 实例。
  4. 然后,它根据 Settings 对象评估 settings.gradle 文件。
  5. 它根据配置的 Settings 对象创建项目的层次结构。
  6. 最后,它将针对其项目执行每个 build.gradle 文件。

6. 总结

我们已经看到,不同的 Gradle 配置文件如何实现各种开发目的。我们可以根据项目的需要使用它们来配置 Gradle 构建以及 Gradle 本身。


说明:
本文中的部分配置示例(如 compiletestCompile 依赖配置以及 jcenter() 仓库)在较新版本的 Gradle 中已被标记为过时或废弃。建议在新项目中参考官方文档使用 implementation 等最新配置及推荐的仓库源。