了解使用子项目和组合构建构建 Gradle 项目的基础知识。

在本节中,您将:

  • 了解多项目构建

  • 了解复合构建

  • 将子项目添加到您的构建中

  • 将构建添加到您的构建中

步骤 0. 开始之前

  1. 您在第 1 部分中初始化了 Java 应用程序。

  2. 您从第 2 部分了解了 Gradle 构建生命周期。

步骤 1. 关于多项目构建

通常,构建包含多个项目,例如将在您的生态系统中部署的共享库或单独的应用程序。

在 Gradle 中,多项目构建包括:

  • settings.gradle(.kts)代表您的 Gradle 构建的文件,包括所需的子项目,例如 include("app", "model", "service")

  • build.gradle(.kts)以及相应子目录中每个子项目的源代码

我们的构建当前由一个名为 的根项目组成authoring-tutorial,它有一个app子项目:

.   (1)
├── app (2)
│   ... (3)
│   └── build.gradle.kts (4)
└── settings.gradle.kts  (5)
1 The authoring-tutorial root project
2 The app subproject
3 The app source code
4 The app build script
5 The optional settings file
.   (1)
├── app (2)
│   ... (3)
│   └── build.gradle (4)
└── settings.gradle  (5)
1 The authoring-tutorial root project
2 The app subproject
3 The app source code
4 The app build script
5 The optional settings file

步骤 2. 将另一个子项目添加到构建中

想象一下,我们的项目正在增长,需要一个自定义库才能运行。

让我们创造这个想象lib。首先,创建一个lib文件夹:

mkdir lib
cd lib

创建一个名为的文件build.gradle(.kts)并向其中添加以下行:

lib/build.gradle.kts
plugins {
    id("java")
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.9.3")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation("com.google.guava:guava:32.1.1-jre")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

tasks.register("task3"){
    println("REGISTER TASK3: This is executed during the configuration phase")
}

tasks.named("task3"){
    println("NAMED TASK3: This is executed during the configuration phase")
    doFirst {
        println("NAMED TASK3 - doFirst: This is executed during the execution phase")
    }
    doLast {
        println("NAMED TASK3 - doLast: This is executed during the execution phase")
    }
}
lib/build.gradle
plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.3'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    implementation 'com.google.guava:guava:32.1.1-jre'
}

test {
    useJUnitPlatform()
}

tasks.register('task3') {
    println('REGISTER TASK3: This is executed during the configuration phase')
}

tasks.named('task3') {
    println('NAMED TASK3: This is executed during the configuration phase')
    doFirst {
        println('NAMED TASK3 - doFirst: This is executed during the execution phase')
    }
    doLast {
        println('NAMED TASK3 - doLast: This is executed during the execution phase')
    }
}

你的项目应该是这样的:

.
├── app
│   ...
│   └── build.gradle.kts
├── lib
│   └── build.gradle.kts
└── settings.gradle.kts
.
├── app
│   ...
│   └── build.gradle
├── lib
│   └── build.gradle
└── settings.gradle

让我们向lib子项目添加一些代码。创建一个新目录:

mkdir -p lib/src/main/java/com/gradle

创建一个 Java 类,CustomLib在名为的文件中调用CustomLib.java,源代码如下:

lib/src/main/java/com/gradle/CustomLib.java
package com.gradle;

public class CustomLib {
    public static String identifier = "I'm a String from a lib.";
}

该项目现在应具有以下文件和目录结构:

.
├── app
│   ├── build.gradle.kts
│   └── src
│       └── main
│           └── java
│               └── authoring
│                   └── tutorial
│                       └── App.java
├── lib
│   ├── build.gradle.kts
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── gradle
│                       └── CustomLib.java
└── settings.gradle.kts
.
├── app
│   ├── build.gradle
│   └── src
│       └── main
│           └── java
│               └── authoring
│                   └── tutorial
│                       └── App.java
├── lib
│   ├── build.gradle
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── gradle
│                       └── CustomLib.java
└── settings.gradle

但是,lib子项目不属于构建,您将无法执行task3,直到将其添加到settings.gradle(.kts)文件中。

要添加lib到构建中,请settings.gradle(.kts)相应地更新根目录中的文件:

settings.gradle.kts
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}

rootProject.name = "authoring-tutorial"

include("app")
include("lib") // Add lib to the build
settings.gradle
plugins {
    id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}

rootProject.name = 'authoring-tutorial'

include('app')
include('lib') // Add lib to the build

让我们将lib子项目添加为app依赖项app/build.gradle(.kts)

app/build.gradle.kts
dependencies {
    implementation(project(":lib")) // Add lib as an app dependency
}
app/build.gradle
dependencies {
    implementation(project(':lib')) // Add lib as an app dependency
}

更新app源代码以便导入lib

应用程序/src/main/java/authoring/tutorial/App.java
package authoring.tutorial;

import com.gradle.CustomLib;

public class App {
    public String getGreeting() {
        return "CustomLib identifier is: " + CustomLib.identifier;
    }

    public static void main(String[] args) {
        System.out.println(new App().getGreeting());
    }
}

最后,让我们app使用以下命令运行./gradlew run

$ ./gradlew run

> Configure project :app

> Task :app:processResources NO-SOURCE
> Task :lib:compileJava
> Task :lib:processResources NO-SOURCE
> Task :lib:classes
> Task :lib:jar
> Task :app:compileJava
> Task :app:classes

> Task :app:run
CustomLib identifier is: I'm a String from a lib.

BUILD SUCCESSFUL in 11s
8 actionable tasks: 6 executed, 2 up-to-date

我们的根项目构建authoring-tutorial现在包括两个子项目,applibapp依赖于取决于lib。您可以lib独立于app.然而,要构建app,Gradle 也会构建lib

第 3 步:了解组合构建

复合构建只是包含其他构建的构建。

复合构建允许您:

  • 从项目构建中提取构建逻辑(并在子项目中重复使用它)

  • 组合通常独立开发的构建(例如插件和应用程序)

  • 将大型构建分解为更小、更独立的块

步骤 4. 将构建添加到构建中

让我们在构建中添加一个插件。首先,创建一个新目录,license-plugin名为gradle

cd gradle
mkdir license-plugin
cd license-plugin

进入gradle/license-plugin目录后,运行gradle init.确保Gradle plugin为以下任务选择项目以及其他选项init

$ gradle init --dsl kotlin --type kotlin-gradle-plugin --project-name license
$ gradle init --dsl groovy --type groovy-gradle-plugin --project-name license

对于任何其他提示,请选择默认值。

你的项目应该是这样的:

.
├── app
│   ...
│   └── build.gradle.kts
├── lib
│   ...
│   └── build.gradle.kts
├── gradle
│    ├── ...
│    └── license-plugin
│        ├── settings.gradle.kts
│        └── plugin
│            ├── gradle
│            │   └── ....
│            ├── src
│            │   ├── functionalTest
│            │   │   └── ....
│            │   ├── main
│            │   │   └── kotlin
│            │   │       └── license
│            │   │           └── LicensePlugin.kt
│            │   └── test
│            │       └── ...
│            └── build.gradle.kts
│
└── settings.gradle.kts
.
├── app
│   ...
│   └── build.gradle
├── lib
│   ...
│   └── build.gradle
├── gradle
│    ├── ...
│    └── license-plugin
│        ├── settings.gradle
│        └── plugin
│            ├── gradle
│            │   └── ....
│            ├── src
│            │   ├── functionalTest
│            │   │   └── ....
│            │   ├── main
│            │   │   └── groovy
│            │   │       └── license
│            │   │           └── LicensePlugin.groovy
│            │   └── test
│            │       └── ...
│            └── build.gradle
│
└── settings.gradle

花点时间查看LicensePlugin.kt代码LicensePlugin.groovygradle/license-plugin/settings.gradle(.kts)文件。值得注意的是,这是一个完全独立的构建,具有自己的设置文件和构建脚本:

gradle/license-plugin/settings.gradle.kts
rootProject.name = "license"
include("plugin")
gradle/license-plugin/settings.gradle
rootProject.name = 'license'
include('plugin')

要将我们的license-plugin构建添加到根项目,请settings.gradle(.kts)相应地更新根文件:

settings.gradle.kts
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}

rootProject.name = "authoring-tutorial"

include("app")
include("subproject")

includeBuild("gradle/license-plugin") // Add the new build
settings.gradle
plugins {
    id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}

rootProject.name = 'running-tutorial-groovy'

include('app')
include('lib')

includeBuild('gradle/license-plugin')

./gradlew projects您可以通过在根文件夹中运行来查看根项目的结构authoring-tutorial

$ ./gradlew projects

------------------------------------------------------------
Root project 'authoring-tutorial'
------------------------------------------------------------

Root project 'authoring-tutorial'
+--- Project ':app'
\--- Project ':lib'

Included builds
\--- Included build ':license-plugin'

我们的根项目构建authoring-tutorial现在包括两个子项目applib,以及另一个构建license-plugin.

在项目根目录中运行:

  • ./gradlew build- 构建applib

  • ./gradlew :app:build- 构建applib

  • ./gradlew :lib:build-lib仅构建

  • ./gradlew :license-plugin:plugin:build-license-plugin仅构建

使用 Gradle 设计项目架构的方法有很多种。

多项目构建非常适合组织具有许多模块的项目,例如mobile-appweb-appapilib、 以及documentation它们之间具有依赖关系的项目。

复合(包含)构建非常适合分离构建逻辑(即约定插件)或测试系统(即修补库)

下一步: 设置文件>>