webflux的探索与实战 - 壹 Gradle: 1. 多模块

297 阅读4分钟

Gradle 多模块

如果你十分熟悉 Gradle 的使用,可能你会觉得我接下来要讲的内容很蠢。因为对于 Gradle 来讲,一个多模块项目的构建是非常非常简单的。 但是对于当时第一次接触到Gradle的我来讲,这个问题也折磨了我一段时间。这篇文章作为存货已经囤积很久了,我想也是时候拿出来水一水更新了。

FEEA0E834861B2019EB034756E37D54A.jpg

模块配置

对于一个基础的 Gradle 项目来讲,它的结构大概是这样的:

由于我是使用 Gradle Kotlin DSL 的,所以你会发现配置脚本的结尾都会有个 .kts

root
  ├── src
  │    ├─ main/java
  │    ├─ main/resources
  │    ├─ test/java
  │    └─ test/resources
  │
  ├── build.gradle.kts 
  ├── gradle.properties
  └── settings.gradle.kts

这时候,如果我想要将其配置为一个多模块的项目,比如变成如下结构:

root
  ├── overtime-common  ---->  第一个模块
  │         └── src
  │              ├─ main/java
  │              ├─ main/resources
  │              ├─ test/java
  │              └─ test/resources
  │ 
  ├── overtime-app  ------->  第二个模块
  │         └── src
  │              ├─ main/java
  │              ├─ main/resources
  │              ├─ test/java
  │              └─ test/resources
  ├── build.gradle.kts
  ├── gradle.properties
  └── settings.gradle.kts

其实这是很简单的,你只需要在 settings.gradle.kts 这么配置:

include("overtime-common")
include("overtime-app")

或者说直接一步到位:

include("overtime-common", "overtime-app")

这就代表将项目中的 overtime-commonovertime-app 作为子项目加载进来。很容易不是么?

724303FEE81913ED608A730162EA1FF3.jpg

那么我们继续往下看,现在假设我希望我的项目是这样的:

root
 ├── commons  
 │      ├── common-core                  -------> 子模块
 │      ├── common-domain                -------> 子模块
 │      ├── common-application           -------> 子模块
 │      └── common-repository            -------> 子模块
 │
 ├── services
 │       ├── user
 │       │    ├── user-domain               ----> 子模块
 │       │    ├── user-api                  ----> 子模块
 │       │    ├── user-repository           ----> 子模块
 │       │    ├── user-service              ----> 子模块
 │       │    ├── user-service-impl         ----> 子模块
 │       │    ├── user-controller           ----> 子模块
 │       │    └── user-application          ----> 子模块
 │       │
 │       ├── compensate
 │       │    ├── compensate-domain         ----> 子模块
 │       │    ├── compensate-api            ----> 子模块
 │       │    ├── compensate-repository     ----> 子模块
 │       │    ├── compensate-service        ----> 子模块
 │       │    ├── compensate-service-impl   ----> 子模块
 │       │    ├── compensate-controller     ----> 子模块
 │       │    └── compensate-application    ----> 子模块
 │       │
 │       │
 │       └── 其他...
 │
 ├── build.gradle.kts
 ├── gradle.properties
 └── settings.gradle.kts

简单来说,我希望能有一个存放所有公共模块的 overtime-common 父模块,来统一配置所有的"公共模块"; 我还希望能有一个存放所有实际业务服务模块的 services 父模块,来统一配置所有的服务模块。 而对于服务模块来讲,每个不同的服务都会有那么固定的7个小的子模块来细分模块之间的职责,比如 -api 模块为 -controller 提供约束、-service-service-impl 提供约束等等。

E9E76596168D395F22EE8BE8970A0F5B.jpg

当时我的脑海中想到这个问题的时候,第一反应是去查了查"如何配置Gradle多模块" 或者 "Gradle 嵌套模块",因为基于我对于 Maven 的认知,在 Maven 中,每个模块的每个子模块都需要配置它对应的父模块,且父模块也要配置其下的所有子模块。当时的我认为,Gradle也许也许要类似的配置。 然而查询的结果显而易见,我并没有找到我想要的答案。直到我查询了 Gradle 的官方文档才恍然大悟:

include("overtime-commons:common-core")
include("overtime-commons:common-domain")
include("overtime-commons:common-application")
include("overtime-commons:common-repository")

include("services:user:user-domain")
include("services:user:user-api")
include("services:user:user-repository")
include("services:user:user-service")
// 以及其他...

实际上,只需要通过 : 代替路径中的 /, 按照从根项目开始的路径将他们添加进去即可。当我第一次尝试出这样的结果后不由得轻声感叹,并在心里默默的指责了一声给我留下了刻板印象的Maven。

但是你会发现,如果真的这么写,如果项目变多了,你要写的 include 也是会非常多的。比如现在我这个项目中,光 service 下的服务模块就有4个,每个模块都算上那7个小模块的话,就要有28个模块了。 但是幸运的是,gradle的配置是以脚本的方式进行配置的,你可以很轻松的去做一些"特别的"事情,比如这样:

includeServices("user")
includeServices("compensate")
// 其他...

val modules = listOf(
    "domain", "repository",
    "service", "service-impl",
    "api", "controller", "application"
)

fun Settings.includeServices(name: String) {
    modules.forEach { module ->
        include("services:$name:$name-$module")
    }
}

你可以通过自定义一些函数来轻松的做到一些xml做不到的事情,可谓是十分便利了。 通过上面这个方式,只需要一个 includeServices 就可以一次性增加对应模块下的7个相关的子模块了,妙哉妙哉~

D6615CBF8C6E61D32F82628CBF0557E3.jpg