多模块 Gradle 项目的库模块依赖方式
相关概念:gradle
在多模块 Gradle 项目里,库模块给业务模块使用,常见就两种方式:
- 直接依赖兄弟模块
- 先发布成 jar,再像普通依赖一样引用
项目内直接依赖
如果 app -> lib1 -> lib2 都在同一个仓库里,最直接的做法就是:
dependencies {
implementation(project(":lib1"))
}而 lib1 再决定自己怎样暴露 lib2:
dependencies {
api(project(":lib2"))
}api 和 implementation 的区别只记一件事
api 会把依赖继续暴露出去,implementation 不会。
也就是说:
lib1用api(project(":lib2")),那app只依赖lib1就够了lib1用implementation(project(":lib2")),那app如果也要直接用lib2的类型,就得自己再显式依赖一次
这件事本质上不是语法选择,而是在声明:
lib2到底是不是lib1对外 API 的一部分。
什么时候该发布成 jar
如果这个库不仅给当前仓库里的兄弟模块用,还要给别的项目复用,就更适合发布成制品。
Gradle 里最常见的是用 maven-publish:
plugins {
kotlin("jvm") version "1.9.20"
`maven-publish`
}
group = "org.looko"
version = "0.0.1-SNAPSHOT"
publishing {
publications {
register(project.name, MavenPublication::class) {
from(components["java"])
}
}
repositories {
mavenLocal()
}
}经验
在多模块项目里,先想清楚“模块边界”比先写依赖更重要:
- 仅供内部实现使用的依赖,用
implementation - 需要被下游模块感知的类型,再用
api - 需要跨仓库复用时,再考虑发布到 Maven 仓库
边界一旦模糊,后面通常会变成“到处能依赖,但谁也说不清为什么能依赖”。