开篇词
该指南将引导你使用 Gradle 构建简单的 Java 项目。
你将创建的应用
你将借助 Gradle 构建一个简单的应用。
你将需要的工具
大概 15 分钟左右;你最喜欢的文本编辑器或集成开发环境(IDE)JDK 6 或更高版本;
如何完成这个指南
像大多数的 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过你已经熟悉的基本设置步骤。如论哪种方式,你最终都有可以工作的代码。
要从头开始,移步至设置项目;要跳过基础,执行以下操作:
下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行 clone 操作:git clone https://github.com/spring-guides/gs-gradle.git切换至 gs-gradle/initial 目录;跳转至该指南的安装 Gradle。
待一切就绪后,可以检查一下 gs-gradle/complete 目录中的代码。
设置项目
首先,为 Gradle 设置一个 Java 项目。为了将注意力集中在 Gradle 上,先使该项目尽可能的简单。
创建目录结构
在选择的项目目录中,创建以下自目录结构;例如,在 Linux 系统上使用 mkdir -p src/main/java/hello:
└── src
└── main
└── java
└── hello
在 src/main/java/hello 目录中,我们可以创建 Java 类。为简单起见以及与该指南的其余部分保持一致,Spring 建议创建两个类:HelloWorld.java 和 Greeter.java。 src/main/java/hello/HelloWorld.java
package hello;
public class HelloWorld {
public static void main(String[] args) {
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
src/main/java/hello/Greeter.java
package hello;
public class Greeter {
public String sayHello() {
return "Hello world!";
}
}
安装 Gradle
现在我们有了可以使用 Gradle 来构建的项目,我们开始安装 Gradle。
强烈建议使用其中一个安装程序:
SDKMANHomebrew
当这些工具都不满足我们的需求时,我们可以从 https://www.gradle.org/downloads 来获取二进制文件。仅需二进制文件即可,因此请查找 gradle-version-bin.zip 所对应的链接。(我们可以选择 gradle-version-all.zip 以获取源代码、文档以及二进制文件。)
将文件解压缩,并将 bin 目录添加至环境变量中。
要测试 Gradle 的安装,请在命令行运行 Gradle:
gradle
如果一切顺利,我们会看到以下消息:
:help
Welcome to Gradle 2.3.
To run a build, run gradle ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
BUILD SUCCESSFUL
Total time: 2.675 secs
我们现在已经安装了 Gradle。
看一下 Gradle 能做什么
在为项目创建 build.gradle 文件之前,我们可以查看它能执行的任务都有哪些:
gradle tasks
我们应该看到可用任务列表。当我们在没有 build.gradle 文件的目录中运行 gradle 时,我们只能看到基本的任务,例如:
:tasks
== All tasks runnable from root project
== Build Setup tasks
setupBuild - Initializes a new Gradle build. [incubating]
== Help tasks
dependencies - Displays all dependencies declared in root project 'gs-gradle'.
dependencyInsight - Displays the insight into a specific dependency in root project 'gs-gradle'.
help - Displays a help message
projects - Displays the sub-projects of root project 'gs-gradle'.
properties - Displays the properties of root project 'gs-gradle'.
tasks - Displays the tasks runnable from root project 'gs-gradle'.
To see all tasks and more detail, run with --all.
BUILD SUCCESSFUL
Total time: 3.077 secs
尽管这些任务是可用的,但如果没有项目构建配置,它们的价值也只限于此。当我们充实 build.gradle 文件后,会有更实用的任务。当我们将插件添加至 build.gradle 时,任务列表将增加,因此我们会经常查看有哪些可用的任务。
接下来我们将添加一个用以启用基本 Java 构建功能的插件:
构建 Java 代码
从简单开始,在该指南开头创建的 中创建一个基本的 build.gradle 文件,它只有一行配置:
apply plugin: 'java'
这一行配置非常有用。再次运行 Gradle 任务时我们将看到任务列表中有新的任务,包括用于构建项目、创建 JavaDoc 以及运行测试的任务。
我们会经常使用 Gradle 来构建任务。该任务将编译、测试代码并将其组成为一个 JAR 文件。我们可以这样来运行它:
gradle build
几秒后,“BUILD SUCCESSFUL” 的显示表明构建已完成。
要查看构建工作的结果,请查看构建目录。我们将在其中找到几个目录,其中包括以下三个经典的目录:
classes:项目的已编译 .class 文件;reports:构建所产生的报告(例如测试报告);libs:组装的项目库(通常是 JAR 和/或 WAR 文件)。
classes 文件夹包含通过编译 Java 代码所生成的 .class 文件。具体来说,我们应该找得到 HelloWorld.class 和 Greeter.class。
此时,该项目没有任何库依赖关系,因此 dependency_cache 目录中没有任何内容。
reports 文件夹应该包含项目上正在运行的单元测试报告。由于该项目尚无任何单元测试,因此该报告将没有意义。
libs 文件夹应包含以该项目目录来命名的 JAR 文件。接下来,我们将看到 JAR 名称以及版本的指定方式。
声明依赖
该 Hello World 示例是完全无依赖的,没有任何的依赖。二大多数的应用都依赖于第三方库来处理常见的以及/或复杂的功能实现。
例如,假设除了输出 “Hello World!” 外,我们希望该应用还能打印当前日期。我们可以使用 Java 库中自带的日期和时间工具,也可以使用 Joda Time 库来使事情变得更有趣。
首先,将 HelloWorld.java 改成:
package hello;
import org.joda.time.LocalTime;
public class HelloWorld {
public static void main(String[] args) {
LocalTime currentTime = new LocalTime();
System.out.println("The current local time is: " + currentTime);
Greeter greeter = new Greeter();
System.out.println(greeter.sayHello());
}
}
在这里,HelloWorld 借助 Joda Time 的 LocalTime 类来获取并打印当前时间。
如果我们现在运行 gradle build 来构建项目,构建将会失败,因为我们还未在构建中将 Joda Time 声明为编译时依赖。
对初学者来说,我们需要添加第三方库的源。
repositories {
mavenCentral()
}
repositories 块指示构建应从 Maven 仓库中解析其依赖项。Gradle 在很大程度上依赖于 Maven 构建工具所建立的许多约定以及功能,包括使用 Maven 作为依赖库源头的选项。
我们已经准备好了第三方库,进行一下声明操作:
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
借助于 dependencies 块,我们可以为 Joda Time 声明一个单一依赖。具体来说,我们从 joda-time 组中获取版本为 2.2 的库。
另一个需要注意的是,它是一个 compile (编译时)依赖,表明它仅在编译时可用(以及如果我们正在构建 WAR 文件时,包含至 WAR 的 /WEB-INF/libs 目录中)。其他值得注意的依赖类型包括:
providedCompile:编译项目代码所需的依赖,但在运行时将由运行该代码的运行容器(例如 Java Servlet API)来提供;testCompile:用于编译和运行测试的依赖,但对于构建或运行项目的运行时代码时则不是必要的。
最后,我们来指定 JAR 工件的名称:
jar {
baseName = 'gs-gradle'
version = '0.1.0'
}
jar 块指定了 JAR 文件的名称。这种情况下,它将被渲染为 gs-gradle-0.1.0.jar。
如果我们现在运行 gradle build,Gradle 应该可以从 Maven 仓库中解析 Joda Time 的依赖并且构建将成功。
结合 Gradle Wrapper 来构建项目
Gradle Wrapper 是开始 Gradle 构建的首选方案。它由 Widows 的批处理脚本、OS X 以及 Linux 的 Shell 脚本所组成。这些脚本允许我们在无需安装 Gradle 的情况下运行 Gradle 构建。这曾经是要添加到构建文件中的内容,但已被折叠至 Gradle 中,所以不再需要进行声明。取而代之的是只需要使用以下命令:
$ gradle wrapper --gradle-version 2.13
在该任务完成之后,我们会注意到一些新文件。这两个脚本位于目录的根路径中,而包装好的 jar 以及属性文件已被添加至新的 gradle/wrapper 目录中。
└──
└── gradlew
└── gradlew.bat
└── gradle
└── wrapper
└── gradle-wrapper.jar
└── gradle-wrapper.properties
现在,Gradle 包装器可以被用于构建项目。将其添加至我们的版本控制系统中,然后每一个 clone 项目的人都可以以相同的方式对其进行构建操作。它的使用方式与安装版的 Gradle 完全一致。运行包装器脚本以执行构建任务,和之前一样:
./gradlew build
在首次给指定版本的 Gradle 运行包装器时,它将下载并缓存该版本的 Gradle 二进制文件。Gradle 包装器文件旨在提交至源码控制系统,因此任何人都可以在无需先安装和配置特定版本的 Gradle 的情况下构建项目。
在该阶段,代码已构建完成,我们可以看到结果:
build
├── classes
│ └── main
│ └── hello
│ ├── Greeter.class
│ └── HelloWorld.class
├── dependency-cache
├── libs
│ └── gs-gradle-0.1.0.jar
└── tmp
└── jar
└── MANIFEST.MF
其中包括 Greeter 和 HelloWorld 的两个预期的类文件,以及一个 JAR 文件。来看一下:
$ jar tvf build/libs/gs-gradle-0.1.0.jar
0 Fri May 30 16:02:32 CDT 2014 META-INF/
25 Fri May 30 16:02:32 CDT 2014 META-INF/MANIFEST.MF
0 Fri May 30 16:02:32 CDT 2014 hello/
369 Fri May 30 16:02:32 CDT 2014 hello/Greeter.class
988 Fri May 30 16:02:32 CDT 2014 hello/HelloWorld.class
类文件绑定在一起。需要注意的是,即使我们将 joda-time 声明为依赖,该库也未被包含在此处。并且 JAR 文件也无法运行。
为了让该代码可以被运行,我们可以借助 Gradle 的 application 插件。将其添加至 build.gradle 文件。
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
我们可以尝试运行该应用:
$ ./gradlew run
结果如下:
:compileJava UP-TO-DATE
:proce***esources UP-TO-DATE
:classes UP-TO-DATE
:run
The current local time is: 16:16:20.544
Hello world!
BUILD SUCCESSFUL
Total time: 3.798 secs
要绑定依赖,我们需要更多的思考。例如,如果我们要构建的是一个 WAR 文件,则可以借助 Gradle 的 WAR 插件来进行一种通常与第三方依赖相关的格式的打包。如果我们使用的是 SpringBoot 以及想要一个可运行的 JAR 文件,那 spring-boot-gradle-plugin 将非常便利。在该阶段,Gradle 对我们系统的了解不够深,无法做出选择。但就目前而言,这些选项应该足以让我们开始使用 Gradle。
为了完善该指南的内容,以下是完整的 build.gradle 文件: build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
mainClassName = 'hello.HelloWorld'
// tag::repositories[]
repositories {
mavenCentral()
}
// end::repositories[]
// tag::jar[]
jar {
baseName = 'gs-gradle'
version = '0.1.0'
}
// end::jar[]
// tag::dependencies[]
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
}
// end::dependencies[]
// tag::wrapper[]
// end::wrapper[]
这里嵌入了许多开始/结束注释。这样就可以将构建文件的块提取到该指南中,以进行上述的详细解说。我们在生产环境的构建文件中不需要它们。
概述
恭喜你!我们创建了一个简单而有效的 Gradle 构建文件,用于构建 Java 项目。
参见
以下指南也可能会有所帮助:
借助 Maven 来构建 Java 项目(尽请期待~)
想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南》