Maven 多医院分支场景下 groupId 的设计与 Jenkins 落地实践

一、背景

同一套系统,交付给不同医院使用,每家医院一个代码分支。构建产物需要区分医院,同时还要考虑后续的升级、合并与维护成本。

在这个场景下,一个常见的困惑是:

pom.xml 里的 groupId 到底要不要按医院区分?它必须唯一吗?

本文把这个问题讲清楚,并给出 Jenkins 落地方案。

二、先理解 Maven 坐标

Maven 定位一个构件,靠的是三元组(GAV):

复制代码
groupId + artifactId + version
  • groupId:项目所属组织或命名空间,通常用反向域名,如 com.yourcompany.his
  • artifactId:项目或模块名,如 his-web
  • version:版本号,如 1.0.0

唯一性约束作用在 GAV 三者组合上,而不是单独某个字段。

Maven 把构件存入仓库时,路径由 GAV 生成:

复制代码
com/yourcompany/his/his-web/1.0.0/his-web-1.0.0.jar

如果两个构件的 GAV 完全相同,后构建的会覆盖先构建的。

三、groupId 是否必须唯一

分两层看:

  1. Maven 坐标层面 :GAV 组合必须唯一。单看 groupId,Maven 不强制全局唯一。
  2. 业务层面 :是否用 groupId 区分医院,是管理策略问题,不是技术强制。

所以 groupId 本身不要求唯一,真正要求唯一的是 GAV。

四、多医院分支的两种方案

方案一:groupId 统一,用 version 区分医院

xml 复制代码
<!-- 医院 A -->
<groupId>com.yourcompany.his</groupId>
<artifactId>his-web</artifactId>
<version>1.0.0-hospitalA</version>

<!-- 医院 B -->
<groupId>com.yourcompany.his</groupId>
<artifactId>his-web</artifactId>
<version>1.0.0-hospitalB</version>

优点:

  • 代码基线统一,升级、合并成本低
  • 依赖引用时 groupId、artifactId 不变,只换 version
  • 符合"同一产品多版本"的常规做法

缺点:

  • version 需要带上医院标识,命名规则要统一

方案二:artifactId / version 相同,用 groupId 区分医院

xml 复制代码
<!-- 医院 A -->
<groupId>com.yourcompany.his.hospitalA</groupId>
<artifactId>his-web</artifactId>
<version>1.0.0</version>

<!-- 医院 B -->
<groupId>com.yourcompany.his.hospitalB</groupId>
<artifactId>his-web</artifactId>
<version>1.0.0</version>

优点:

  • 仓库天然隔离,依赖方一眼能看出是哪家医院

缺点:

  • 公共代码升级时,所有 groupId 都要维护
  • 容易导致代码分叉,后期难以合并

关键结论

如果 artifactId 和 version 都一样,那么 groupId 必须不同,否则 GAV 冲突,构件互相覆盖。

这是硬性约束,不是可选项。

五、方案选择建议

场景 建议
各医院只是配置或少量定制 groupId 统一,用 version 区分
各医院定制差异大,接近独立产品 可以用不同 groupId,但要接受维护成本
artifactId / version 已固定不变 groupId 必须按医院区分
多模块项目 父 groupId 统一,子模块继承,不要按医院拆

多数情况下,统一 groupId、用 version 区分医院是更省事、更可持续的做法。

六、Jenkins 落地

Jenkins 负责把上面的坐标策略自动化执行。核心流程:

  1. 拉取分支:按医院从 Git 拉取对应分支
  2. 注入版本 :用构建参数或 BUILD_NUMBER 动态设置 version
  3. 执行构建 :mvn clean package
  4. 发布构件 :mvn deploy 到远程仓库

参数化构建示例

定义一个参数 HOSPITAL,取值为 hospitalA、hospitalB。

在 pom.xml 中使用属性:

xml 复制代码
<groupId>com.yourcompany.his</groupId>
<artifactId>his-web</artifactId>
<version>1.0.0-${hospital}</version>

Jenkins 构建命令:

bash 复制代码
mvn clean package -Dhospital=${HOSPITAL}

这样同一套代码,通过参数就能产出不同医院的构件,GAV 互不冲突。

多分支流水线

如果每家医院一个分支,可以用 Jenkins 的 Multibranch Pipeline:

  • 每个分支自动生成一个 Job
  • 分支名映射到医院标识
  • 构建时自动注入对应 version

七、常见误区

误区一:不同医院必须用不同 groupId

不是。真正决定冲突的是 GAV 组合。只要 artifactId 或 version 不同,同一个 groupId 下可以共存多个构件。

误区二:groupId 相同会冲突

只有 GAV 完全相同时才会冲突。groupId 相同、version 不同,完全没问题。

误区三:用 groupId 区分医院更清晰

短期看清晰,长期看是维护负担。除非各医院已接近独立产品,否则不建议。

八、总结

  1. Maven 的唯一性约束在 GAV 组合,不在单个 groupId。
  2. 多医院分支场景,groupId 不是必须唯一。
  3. artifactId 和 version 相同时,groupId 必须不同,否则冲突。
  4. 多数情况推荐:统一 groupId,用 version 区分医院。
  5. Jenkins 通过参数化构建或多分支流水线,把坐标策略自动化落地。

一句话:坐标设计是策略,Jenkins 是执行。策略选对,维护成本才可控。

相关推荐
毕业设计70318 小时前
(免费领源码)基于node的学生公寓管理系统06412- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·mysql·node.js·maven·mybatis·express·b/s
知守观1 天前
同事的 SNAPSHOT 更新了,我三天后才拉到:Maven 更新检查被 _remote.repositories 静默跳过
java·后端·maven
知守观1 天前
Maven SNAPSHOT 更新排查:-U 无效、clean 无用,问题在 _remote.repositories(附完整链路)
java·后端·maven
wangfenglei1234562 天前
jenkins权限配置
运维·jenkins
骑着蜗牛撵大象3272 天前
CentOS 7 单机拉起 Elasticsearch 7.17.29:从内核报错到公网可达的全链路记录
elasticsearch·centos·jenkins·restful·内核调优·公网部署
打工仔折腾 AI2 天前
CentOS 7 单机部署 Elasticsearch 7.17.29:启动报错排查与 CRUD 验证
人工智能·后端·python·elasticsearch·性能优化·centos·jenkins
知守观2 天前
多模块工程没 install,跑起来的代码是上周的:Maven reactor 依赖解析踩坑
java·maven·intellij idea
西柚不烦恼3 天前
PyCharm 虚拟环境与 Jenkins 自动化部署实践
pycharm·自动化·jenkins
空空dream3 天前
04 | 用 Jenkins 打通 CI自动构建镜像并推送到本地 Harbor
运维·ci/cd·jenkins