4. 根build.gradle与子build.gradle的职责划分
4.1 职责划分原理
在Gradle多模块项目中,根build.gradle和子build.gradle各自承担不同的配置责任。合理的职责划分可以消除重复、降低维护成本、统一构建环境,同时允许子模块保留必要的定制能力。
- 根build.gradle:定义全局属性、公共仓库、公共插件版本(通过
plugins块声明但不 apply)、所有项目或子项目共享的配置(如allprojects和subprojects块)。 - 子build.gradle:仅声明本模块特有的依赖、任务、插件应用、源集配置等,避免重复根级配置。
4.2 allprojects 与 subprojects 块
| 块 | 作用域 | 典型用途 |
|---|---|---|
allprojects | 根项目 + 所有子项目 | 仓库配置、公共插件版本、全局属性 |
subprojects | 仅所有子项目(不含根) | 子类项目通用配置(如 Java 插件、编码、JUnit 版本) |
⚠️ 常见错误:不要将子模块特有的依赖声明放在
subprojects 块中,否则所有子模块都会获得该依赖(即使不需要)。应把公共依赖(如日志门面)放 subprojects,私有依赖放子 build.gradle。
4.3 插件声明位置
Gradle 推荐在根 build.gradle 中使用 plugins 块统一管理插件版本,子模块再通过 plugins 块或 apply 选择性应用。
// 根 build.gradle —— 只声明版本,不 apply
plugins {
id 'org.springframework.boot' version '3.2.1' apply false
id 'java' apply false // Java 插件也以版本方式管理
}
subprojects {
// 子模块公共配置
apply plugin: 'java'
}
子模块只需引用插件 ID(无需版本):
// 子模块 build.gradle(如 service/build.gradle)
plugins {
id 'org.springframework.boot'
id 'java'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
}
4.4 实现流程:典型多模块布局
- 创建根项目:在
settings.gradle中声明所有子模块名称。 - 编写根 build.gradle:配置
allprojects块统一仓库,subprojects块设置通用插件和编译选项。 - 编写子 build.gradle:每个子模块声明自己的依赖、任务和自定义配置。
- 验证配置:运行
gradle projects查看项目层次,运行gradle properties检查继承的属性值。
4.5 职责划分架构图
4.6 调试技巧
- 使用
gradle properties查看当前项目所有属性,区分哪些来自根 build.gradle 的allprojects块。 - 使用
gradle projects检查 project 树是否正确。 - 添加
logger.quiet("root: ${project.rootDir}")到根 build.gradle 验证执行顺序。
💡 最佳实践:将
plugins 版本声明放在根 build.gradle 的 plugins 块内,并设置 apply false。这样子模块直接引用插件名即可,保证版本一致性同时避免重复。
4.7 常见错误与解决方案
| 错误场景 | 原因 | 解决方案 |
|---|---|---|
| 子模块找不到插件 | 根插件版本声明未加 apply false,且子模块未主动 apply | 确保根只用 apply false,子模块显式调用 plugins { id '...' } |
| 全局属性被子模块覆盖 | 子 build.gradle 中使用了同名属性 | 使用 ext 命名空间(如 ext.libVersion = '1.0')并在子模块通过 rootProject.ext 引用 |
| 所有子模块都应用了无关依赖 | 在 subprojects 块中声明了模块私有依赖 | 只将真正共用的依赖放入 subprojects 块,其他放入子 build.gradle |
4.8 性能与稳定性优化
- 避免在 allprojects 中执行耗时代码(如网络请求),因为会作用于根项目,可能造成额外延迟。
- 善用配置避免:
subprojects { afterEvaluate { ... } }仅在子模块评估后执行,减少无用配置。 - 插件管理集中化:所有第三方插件版本仅在根 build.gradle 的
plugins块中定义,避免子模块版本冲突。 - 使用
buildSrc或版本目录(Version Catalog)管理版本号,可进一步提升一致性(第5章将详述)。