读书笔记《gradle-essentials》多国语言项目
我们生活在一个语言不够的时代。开发人员应该是多语种程序员,并为工作选择合适的工具。虽然这始终是一个主观决定,但我们会尝试根据执行速度、开发人员生产力、可用库和资源、团队对语言的舒适度等各种参数来选择语言和生态系统。
当我们已经承担了使用不同语言的认知负担时,Gradle 成为我们的好朋友,因为即使我们正在使用其他语言构建项目,我们也不必更改构建工具。我们甚至可以在同一个项目中使用多种语言,并让 Gradle 为整个项目编排构建。除了一系列基于 JVM 的语言之外,Gradle 还支持 C、C++、Objective C 等来生成原生应用程序。 Gradle 也是 Android 平台的官方构建工具。支持的语言列表正在增加。除了官方插件,还有很多社区支持的语言插件。
尽管在整本书中我们主要关注 Java 作为语言,但我们可以很好地使用 Groovy 或 Scala 来编写示例。 java
插件(连同 java-base
插件,由 java 应用
项目插件)为基于 JVM 的项目提供基本功能。 scala
和 groovy
等语言特定插件扩展了 java
插件以支持以一致的方式常见的成语。所以,一旦我们使用了 java
插件,我们就已经熟悉了 sourceSet
是什么,配置
的工作原理,如何添加库依赖等等,这些知识在我们使用这些语言插件时非常有用。在本章中,我们将了解如何通过添加 Groovy 或 Scala 轻松地为 Java 项目添加更多趣味。
对于 代码示例,在本章中,让我们构建一个简单的每日报价< /span> 服务 根据一年中的某一天返回报价。由于我们商店中的报价可能较少,因此服务应该以循环方式重复报价。同样,像往常一样,我们将尝试使其尽可能简单,更多地关注构建方面而不是应用程序逻辑。我们将创建两个独立的 Gradle 项目来实现完全相同的功能,一次在 Groovy 中,然后在 Scala 中。
在进入特定语言的细节之前,让我们从定义 QotdService
接口开始,它只声明了一个方法,getQuote
。合同是,只要我们通过相同的日期,我们应该得到相同的报价:
实现 getQuote
的逻辑可以使用 Date
以任何方式反对,例如使用包括时间在内的整个日期来确定报价。但是,为了简单起见,我们将在实现中仅使用 Date
对象的日期组件。此外,因为我们希望我们的接口对未来的实现开放,我们让 getQuote
将 Date
对象作为参数。
这个接口是我们将在两个项目中都有的 Java 文件。这只是为了演示 Java 和 Groovy/Scala 源代码在一个项目中的集成。
让我们首先在Groovy 中实现QotdService
接口。此外,我们将编写一些单元测试以确保功能按预期工作。要启动项目,让我们创建如下目录结构:
src/main/java
目录是 Java 源代码的默认目录。同样,默认使用 src/main/groovy
来编译 Groovy 源文件。同样,这只是一个约定,源目录的路径和名称可以通过 sourceSets
轻松配置。
让我们首先为我们的 Groovy 项目编写 构建脚本。在项目根目录中创建一个 build.gradle
文件,内容如下:
构建 Groovy 项目就像构建 Java 项目一样简单。我们不是应用 java
插件,而是应用 groovy
插件,它会自动应用 java
插件给我们。除了应用插件之外,我们还需要将 Groovy 添加为库依赖项,以便它可用于编译,也可在运行时使用。我们还在 testCompile
配置中添加 junit
以便它可用于单元测试。我们将 Maven central 声明为要使用的存储库,但这可以更改为任何可以服务于我们项目依赖项的有效存储库配置。
Note
Gradle 构建脚本是一个 Groovy DSL,部分 Gradle 是用 Groovy 编写的。但是,与 Gradle 本身在运行时依赖的任何其他库一样,Groovy 对我们正在构建的项目并不隐式可用。因此,我们必须明确将 Groovy 声明为项目依赖项,具体取决于我们是在生产源还是测试源中使用 Groovy。
Groovy 插件还负责编译项目中的 Java 源文件。让我们在 Groovy 中实现 QotdService
接口:
服务的实现 接受构造函数中的引号列表。 getQuote
方法通过列表中的索引获取报价。为了确保计算的索引始终保持在报价大小的范围内,我们得到了一年中某一天的模数和列表的大小。
为了测试服务,让我们在 Groovy 中编写非常基本的 JUnit 测试用例:
我们在设置中准备 测试数据,每个测试用例确保报价服务的合同得到维护。由于报价单仅包含两个报价,因此应每隔一天重复一次。
我们可以使用以下代码从命令行运行测试:
在最后一节之后,从应用程序构建的角度来看,这节的大部分内容都是非常可预测的。因此,让我们快速了解一下它的要点。目录结构如下:
所有 Scala 源文件都是从 src/main/scala
和 src/test/scala
读取的,除非使用 sourceSets
。这一次,我们唯一需要应用的插件是 scala
插件,它就像 groovy
插件一样,隐式应用java
插件到我们的项目。让我们为这个项目编写 build.gradle
文件:
在这里,我们必须提供 scala-library
作为依赖项。我们还添加了 specs2
作为测试配置的依赖项。我们正在使用 JUnit runner 进行测试。
Note
specs2
是 一个流行的 Scala 测试库,它支持单元测试和验收测试以及 BDD/TDD写作风格测试。更多信息可在http://etorreborre.github.io/specs2/。
该实现不是非常惯用的 Scala,但这超出了本书的范围。该类在构造函数中采用引号 Seq
并以与 Groovy 对应物类似的方式实现 getQuote
方法。
现在服务已经实现,让我们通过编写单元测试来验证它是否符合 QotdService
的语义。为简洁起见,我们将仅介绍重要的测试用例:
运行测试用例的任务与 Groovy 对应的任务相同。我们可以使用以下代码运行测试:
在本章前面的示例中,我们用Java 声明了一个接口,并分别用Groovy 和Scala 实现了它。这是可能的,因为 java
插件编译的类可用于 Groovy 和 Scala 类。
如果我们希望 Java 类能够访问 Groovy 或 Scala 类进行编译,那么我们必须使用支持的 联合编译 来编译 Java 源文件由各自的插件。 groovy
和scala
插件都支持联合编译,可以编译Java源码。
要在 Java 类中引用 Groovy 类,最简单的方法是将相应的 Java 源文件移动到 src/main/groovy
(或任何 Groovy srcDirs
为 sourceSets
) 配置,Groovy 编译器在编译时使 Java 类可以使用 Groovy 类。 Scala 联合编译也是如此。我们可以将需要 Scala 类进行编译的 Java 文件放在任何 Scala srcDirs
(src/main/scala
默认情况下)。
Gradle 附带的各种语言和其他插件的官方文档链接可以在以下 URL 中找到:
https://docs.gradle.org/current/userguide/standard_plugins。 html