Gradle简介

2025/04/30

1. 概述

Gradle是一个基于Groovy的构建管理系统,专为构建基于Java的项目而设计。

安装说明可在此处找到。

2. 构建块-项目和任务

在Gradle中,构建由一个或多个项目组成,每个项目由一个或多个任务组成

Gradle中的项目可以组装jar、war,甚至zip文件。

任务是一项单独的工作,它可以包括编译类,或创建和发布Java/Web档案。

一个简单的任务可以定义为:

task hello {
    doLast {
        println 'Tuyucheng'
    }
}

如果我们从build.gradle所在的同一位置使用gradle-q hello命令执行上述任务,我们应该在控制台中看到输出。

2.1 任务

Gradle的构建脚本完全是Groovy:

task toLower {
    doLast {
        String someString = 'HELLO FROM BAELDUNG'
        println "Original: "+ someString
        println "Lower case: " + someString.toLowerCase()
    }
}

我们可以定义依赖于其他任务的任务,可以通过在任务定义中传递dependsOn:taskName参数来定义任务依赖关系:

task helloGradle {
    doLast {
        println 'Hello Gradle!'
    }
}

task fromTuyucheng(dependsOn: helloGradle) {
    doLast {
        println "I'm from Tuyucheng"
    }
}

2.2 向任务添加行为

我们可以定义一个任务并通过一些附加行为来增强它:

task helloTuyucheng {
    doLast {
        println 'I will be executed second'
    }
}

helloTuyucheng.doFirst {
    println 'I will be executed first'
}

helloTuyucheng.doLast {
    println 'I will be executed third'
}

helloTuyucheng {
    doLast {
        println 'I will be executed fourth'
    }
}

doFirst和doLast分别在动作列表的顶部和底部添加动作,并且可以在单个任务中定义多次

2.3 添加任务属性

我们还可以定义属性:

task ourTask {
    ext.theProperty = "theValue"
}

在这里,我们将ourTask任务的theProperty设置为“theValue”。

3. 管理插件

Gradle中有两种类型的插件-script和binary。

为了获得附加功能,每个插件都需要经过两个阶段:解析和应用。

解析意味着找到插件jar的正确版本并将其添加到项目的类路径中

应用插件就是在项目上执行Plugin.apply(T)

3.1 应用脚本插件

在aplugin.gradle中,我们可以定义一个任务:

task fromPlugin {
    doLast {
        println "I'm from plugin"
    }
}

如果我们想将这个插件应用到项目build.gradle文件中,需要做的就是将这一行添加到build.gradle中:

apply from: 'aplugin.gradle'

现在,执行gradle tasks命令应该在任务列表中显示fromPlugin任务。

3.2 使用插件DSL应用二进制插件

在添加核心二进制插件的情况下,我们可以添加简称或插件ID:

plugins {
    id 'application'
}

现在,应用程序插件的run任务应该可以在项目中使用,用来执行任何可运行的jar文件。要应用社区插件,我们必须提供完整的插件ID:

plugins {
    id "org.shipkit.bintray" version "2.3.5"
}

现在,Shipkit任务应该在gradle任务列表中可用。

插件DSL的局限性是:

  • 它不支持插件块内的Groovy代码
  • 插件块需要是项目构建脚本中的顶级语句(它之前只允许有buildscripts{}块)
  • 插件DSL不能写在脚本插件、settings.gradle文件或初始化脚本中

插件DSL仍在孵化中,在后续的Gradle版本中,DSL和其他配置可能会有所变更。

3.3 应用插件的传统程序

我们还可以使用“apply plugin”来应用插件:

apply plugin: 'war'

如果我们需要添加社区插件,我们必须使用buildscript{}块将外部jar添加到构建类路径。

然后,我们可以在构建脚本中应用该插件,但只能在任何现有的plugins{}块之后

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "org.shipkit:shipkit:2.3.5"
    }
}
apply plugin: "org.shipkit.bintray-release"

4. 依赖管理

Gradle支持非常灵活的依赖管理系统,它与各种可用的方法兼容。

Gradle中依赖管理的最佳实践是版本控制、动态版本控制、解决版本冲突和管理传递依赖

4.1 依赖配置

依赖被分组到不同的配置中,每个配置都有一个名称,并且它们可以相互扩展

如果我们应用Java插件,我们将拥有可用于分组依赖的“implementation”、“testImplementation”和“runtimeOnly”配置,default配置扩展了“runtimeOnly”

4.2 声明依赖

让我们看一个使用几种不同方式添加一些依赖(Spring和Hibernate)的示例:

dependencies {
    implementation group: 
      'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'
    implementation 'org.springframework:spring-core:4.3.5.RELEASE',
            'org.springframework:spring-aop:4.3.5.RELEASE'
    implementation(
        [group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'],
        [group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE']
    )
    testImplementation('org.hibernate:hibernate-core:5.2.12.Final') {
        transitive = true
    }
    runtimeOnly(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') {
        transitive = false
    }
}

我们在各种配置中声明依赖:各种格式的implementation、testImplementation和runtimeOnly。

有时我们需要包含多个构件的依赖,在这种情况下,我们可以添加一个仅用于构件的@extensionName(或扩展形式的ext)来下载所需的构件:

runtimeOnly "org.codehaus.groovy:groovy-all:2.4.11@jar"
runtimeOnly group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar'

在这里,我们添加了@jar符号来仅下载jar工件而不下载依赖。

要向任何本地文件添加依赖,我们可以使用如下方法:

implementation files('libs/joda-time-2.2.jar', 'libs/junit-4.12.jar')
implementation fileTree(dir: 'libs', include: '*.jar')

当我们想要避免传递依赖时,我们可以在配置级别或依赖级别上进行

configurations {
    testImplementation.exclude module: 'junit'
}
 
testImplementation("org.springframework.batch:spring-batch-test:3.0.7.RELEASE"){
    exclude module: 'junit'
}

5. 多项目构建

5.1 构建生命周期

在初始化阶段,Gradle确定哪些项目将参与多项目构建

这通常在项目根目录下的settings.gradle文件中提及,Gradle还会创建参与项目的实例。

在配置阶段,所有创建的项目实例都基于Gradle特性配置进行按需配置

在此功能中,只需配置必需的项目即可执行特定任务。这样,对于大型多项目构建,可以大大缩短配置时间;此功能仍在孵化中。

最后,在执行阶段,将执行创建和配置的任务子集,我们可以在settings.gradle和build.gradle文件中分别添加代码来感知这三个阶段。

在settings.gradle中:

println 'At initialization phase.'

在build.gradle中:

println 'At configuration phase.'

task configured { println 'Also at the configuration phase.' }

task execFirstTest { doLast { println 'During the execution phase.' } }

task execSecondTest {
    doFirst { println 'At first during the execution phase.' }
    doLast { println 'At last during the execution phase.' }
    println 'At configuration phase.'
}

5.2 创建多项目构建

我们可以在根文件夹中执行gradle init命令来为settings.gradle和build.gradle文件创建骨架。

所有常见配置都将保存在根构建脚本中:

allprojects {
    repositories {
        mavenCentral() 
    }
}

subprojects {
    version = '1.0'
}

设置文件需要包含根项目名称和子项目名称:

rootProject.name = 'multi-project-builds'
include 'greeting-library','greeter'

现在我们需要创建两个名为greet-library和greeter的子项目文件夹,用于演示多项目构建,每个子项目都需要一个单独的构建脚本来配置其各自的依赖和其他必要的配置。

如果我们希望greeter项目依赖于greeter-library,我们需要在greeter的构建脚本中包含依赖:

dependencies {
    implementation project(':greeting-library') 
}

6. 使用Gradle包装器

如果Gradle项目有适用于Linux的gradlew文件和适用于Windows的gradlew.bat文件,我们不需要安装Gradle来构建项目。

如果我们在Windows中执行gradlew build,在Linux中执行./gradlew build,则将自动下载gradlew文件中指定的Gradle发行版。

如果我们想将Gradle包装器添加到我们的项目中:

gradle wrapper --gradle-version 7.2

该命令需要从项目根目录执行,这将创建所有必要的文件和文件夹,以将Gradle包装器绑定到项目;另一种方法是将包装器任务添加到构建脚本中:

wrapper {
    gradleVersion = '7.2'
}

现在我们需要执行wrapper任务,该任务会将我们的项目与wrapper绑定。除了gradlew文件之外,gradle文件夹中还会生成一个wrapper文件夹,其中包含一个jar文件和一个属性文件。

如果我们想切换到新版本的Gradle,我们只需要更改gradle-wrapper.properties中的一个条目。

7. 总结

在本文中,我们研究了Gradle,它在解决版本冲突和管理传递依赖方面比其他现有构建工具具有更大的灵活性。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章