1. 多模块项目结构:settings.gradle 配置、根项目与子项目、include 与项目路径

1.1 为什么需要多模块结构

单体项目随着业务增长会逐渐膨胀,编译时间、代码耦合度、团队协作效率都会急剧下降。多模块结构将工程按业务边界或技术层拆分为独立子项目,每个子项目拥有独立构建脚本,根项目只负责编排和聚合。Gradle 通过 settings.gradle 文件定义模块拓扑,这是多模块构建的唯一入口。

核心原则:Gradle 多模块的模块关系由 settings.gradle 静态声明,运行时不可变。所有子模块的发现、路径解析、任务依赖重组都基于该文件的声明顺序与路径规则。

1.2 根项目与子项目:两种角色

角色位置构建脚本职责
根项目项目最顶层目录build.gradle / build.gradle.kts全局配置、插件声明、子项目公共逻辑
子项目根目录下的子目录各子目录内的 build.gradle业务模块 / 基础库 / 独立组件

根项目本身也可以包含源代码(不推荐),多数场景只作为聚合容器。子项目在 settings.gradle 中通过 include 声明后被自动识别,并继承根项目的 allprojects 或 subprojects 配置块。

1.3 settings.gradle 的核心作用

settings.gradle 位于项目根目录,Gradle 启动时第一个读取的就是它。其核心职责包括:

  • 声明项目名称(rootProject.name)
  • 注册子模块(include 语句)
  • 定义项目路径与物理目录的映射
  • 配置模块间的依赖查找策略
  • 引入复合构建或插件管理
关键顺序:settings.gradle 执行完毕后,Gradle 才会解析各子项目的 build.gradle。settings 中声明的路径直接影响任务调度时的项目引用名。
// settings.gradle — 最小化多模块配置示例
rootProject.name = "my-platform"

include "core"
include "service:user-service"
include "service:order-service"
include "web:admin-console"

1.4 include 与项目路径语法

include 接受一个或多个字符串参数,每个字符串代表一个逻辑项目路径。路径中的冒号 : 是 Gradle 的路径分隔符,对应文件系统的子目录层级。下表列出常见模式:

include 写法实际目录结构(相对于根)项目引用名
include "core"./core/:core
include "service:user-service"./service/user-service/:service:user-service
include "web:admin-console"./web/admin-console/:web:admin-console
include "libs:security"./libs/security/:libs:security

项目引用名(:core、:service:user-service)在跨模块依赖声明、任务名称引用、Gradle 命令行中统一使用。

// 在 build.gradle 中引用子项目的路径
dependencies {
    implementation project(":core")
    implementation project(":service:user-service")
    testImplementation project(":libs:security")
}
避免踩坑:include 路径中的冒号前后不要加空格。include "service : user-service" 会触发项目路径解析异常。路径必须与文件系统目录名严格一致(大小写敏感,Linux/macOS 尤其注意)。

1.5 多模块项目结构图

下图展示了一个典型多模块 Gradle 项目的物理目录与逻辑项目路径的对应关系。根项目作为聚合根,子项目按业务域分层组织。

Gradle 多模块项目结构 — 物理目录与逻辑路径 根项目 :my-platform settings.gradle :core :service :web :service:user-service :service:order-service :web:admin-console 📁 对应物理目录结构 my-platform/ ├── core/ ├── service/ ├── user-service/ ├── order-service/ ├── web/ └── admin-console/ └── settings.gradle

1.6 命令行验证模块结构

配置完成后,通过 Gradle 内置任务可以快速验证模块是否被正确识别:

# 列出所有项目(含根项目)
gradle projects

# 输出示例:
# Root project 'my-platform'
# +--- Project ':core'
# +--- Project ':service'
#      +--- Project ':service:user-service'
#      +--- Project ':service:order-service'
# +--- Project ':web'
#      +--- Project ':web:admin-console'

# 查看特定子项目的属性
gradle :core:properties
调试技巧:如果某子项目没有出现在 gradle projects 列表中,优先检查 settings.gradle 中的 include 路径是否与目录名完全匹配。Windows 系统注意大小写与反斜杠问题,统一使用正斜杠 / 或冒号路径。

1.7 常见错误与解决方案

错误现象根本原因修复方法
Project with path ':xxx' not foundinclude 路径与目录不一致或遗漏声明检查 settings.gradle 并补全 include "xxx"
Settings file 'settings.gradle' not found根目录缺少 settings.gradle在项目根目录创建 settings.gradle
Cannot evaluate root project before settings loaded在 settings.gradle 中引用了项目对象settings 阶段只做声明,不要调用 project API
Duplicate project path两次 include 了相同路径移除重复的 include 声明

1.8 性能优化:合理控制模块粒度

多模块并非越多越好。每个子项目都会增加配置阶段的开销。推荐原则:

  • 按变更边界拆分:一个模块对应一个独立交付单元或业务域
  • 避免过度嵌套:层级深度控制在 2~3 层,过深会增加路径解析成本
  • 利用 includeFlat 快速集成同级模块(适用于扁平结构)
  • 启用配置缓存:在 gradle.properties 中设置 org.gradle.configuration-cache=true
// gradle.properties — 开启配置缓存与并行执行
org.gradle.parallel=true
org.gradle.configuration-cache=true
org.gradle.caching=true
本章小结:settings.gradle 是多模块项目的神经中枢。正确理解根项目 / 子项目角色、掌握 include 路径语法、熟练使用 gradle projects 验证,是后续章节学习任务调度与跨模块依赖管理的基础。下一章将深入 allprojects 与 subprojects 配置块,实现统一插件管理与版本控制。