平台工程手记Maven 架构设计推荐方案

BUILD ONCE. EVOLVE INDEPENDENTLY.

Sparrow Parent 与 BOM按组织边界,划分构建与交付

上游提供构建基线,平台产出组件组合,
下游业务统一接入。
组织内部不把自己产出的 BOM 作为构建前提。

SPARROW 平台架构2026.09.22含官方依据与完整 POM 示例
ONE BASELINE · TWO AUDIENCES
sparrow-parentSpring 生态 · JDK · 构建规范
向下提供继承配置
protocol / core / auth内部组件 · 独立发布
sparrow-bom对外版本组合 · 业务入口

平台组件继承 Parent;业务项目继承或导入 BOM。
组件版本与构建基线分别演进。

01 /

结论先行

按组织的生产与交付边界划分 POM:内部组件依赖上游基线,组织产出的 BOM 提供给下游。对 Sparrow 而言,在 sparrow-shell 下设置 sparrow-parent 与 sparrow-bom 两个 POM 子模块;sparrow-bom 的 parent 也是 sparrow-parent。

01 · STABLE FOUNDATION

内部继承 Parent

协议、核心、认证组件采用稳定的构建与第三方版本基线,分别声明自己的发布版本。

02 · PLATFORM DELIVERY

对外交付 BOM

BOM 继承 Parent、管理公司组件版本;业务可以获得整套规范,也可以仅导入版本管理。

03 · SIMPLE ADOPTION

业务无需重复建设

即使采用多模块,也无需额外维护一套部门级 Parent/BOM;保留工程聚合根即可。

先明确:Maven 的能力,与公司的架构约定

Maven 支持 POM 继承,也支持通过 dependencyManagement 导入 BOM。本方案进一步规定:平台内部组件不继承或导入对外的 sparrow-bom;业务项目可以将它作为 parent。这是为了隔离构建与发布节奏,不是 Maven 对 BOM 的语法限制。

依据:Maven · Dependency Management / Maven · POM Inheritance
02 /

问题背景

sparrow-shell 聚合 Sparrow 自身的功能模块,其中协议层定义公共契约,核心层提供通用能力,认证模块提供登录、令牌与会话等功能。平台组维护这些组件,公司内部的业务平台按需使用;业务项目本身也可能由多个 Maven 模块组成。

讨论的起点是:一个 POM 同时承载 Spring 等开源生态版本、构建插件和 Sparrow 自有组件版本;内部组件又把这个 POM 作为 parent。再配合统一的 sparrow_version,一个组件改版本,就容易牵动整套清单和多个组件的发布版本。

真正需要分开的,是三种变化:构建基线的变化、组件功能的变化,以及对外推荐版本组合的变化。它们不必拥有相同版本号,也不必在同一天发布。

Parent POM · 父配置
给子项目继承的工程规范,例如 JDK、编码、插件和公共依赖管理。
BOM · 版本清单
Bill of Materials,集中列出兼容的组件版本;不自动把所有组件加入项目。
Aggregator · 聚合根
通过 modules 组织一起构建的模块。被聚合不等于继承其配置。
Dependency · 实际依赖
在 dependencies 中声明项目确实使用的库;版本可由父 POM 或 BOM 提供。
聚合与继承是两种关系:Maven · Aggregation。

关联开源项目:让分层有具体落点

下面四个项目把讨论连接到实际代码。简介依据仓库 README;涉及目录或本文建议的地方单独标识。两个 POM 子模块的拆分是本文推荐方案,不表示这些仓库已经完成迁移。

01 / FOUNDATIONREADME 说明

sparrowzoo/sparrow-shell

Java 基础框架的功能模块集合。README 强调从 JDK 基础能力出发,以公共 API 与可替换实现降低耦合,让业务按需选择实现,并保留扩展点。

少依赖、低耦合是其设计方向;“减少依赖”的目标不能理解为当前全部模块都没有第三方依赖。

本文中的位置:平台组件生产侧。重点围绕 protocol、sparrow 核心及认证组件,推荐继承稳定的 sparrow-parent。

02 / VERSION CATALOGREADME 说明

sparrowzoo/sparrow-bom

README 将其定位为 Sparrow 项目集的 BOM 父项目。当前简介较短,主要确认它承担项目集的公共 POM 角色,没有展开完整的发布治理规则。

本文建议的演进:分离稳定的构建与开源生态基线,由 sparrow-parent 承担;sparrow-bom 继承它,并集中交付面向下游的公司组件组合。

03 / SPRING INTEGRATIONREADME 说明

sparrow-os/sparrow-starter

Sparrow 与 Spring 的集成入口。README 介绍了容器桥接、Controller 结果处理、客户端信息与跨域等 Web 支持,以及 Redis 限流、验证码和 MyBatis 等配套适配。

README 也给出 DDD / 整洁架构的接入思路:领域核心保持框架独立,在应用启动层引入 starter 完成集成。

本文中的位置:平台向业务提供的集成组件。作为这条产品线的生产者,建议继承上游基线,再纳入对外 BOM;此处不宣称仓库已采用新 POM 结构。

04 / BUSINESS MODULESREADME + 目录观察

sparrow-os/sparrow-passport-ddd

当前 README 尚未展开项目职责与使用方式。仓库目录可见 passport-domain、passport-application、passport-adapter 等分层,以及 Sparrow、Spring Boot 等运行入口。

本文中的应用场景:用这类业务多模块结构讨论公司 BOM 的接入。仓库当前还存在 bom 目录;“无需额外的业务 BOM”是推荐方向,不是已完成的现状。

功能代码、版本治理、框架接入与业务组织,是不同维度

sparrow-shell 提供基础能力,sparrow-starter 解决 Spring 接入,BOM 负责统一版本组合,多模块业务通过这些能力构建应用。这是本文对项目角色的架构归纳,并不表示四个仓库之间只有一条简单的 Maven 依赖链。

03 /

详细内容

STEP 01先把生产者与使用方分开

平台组是组件的生产者,业务部门是组件的使用方。sparrow-parent 为生产者提供稳定基线;sparrow-bom 继承这套基线,再补上公司组件清单,成为业务的统一入口。

建议的 POM 关系

结构建议 · 尚未修改现有工程

平台组 / 组件生产者

sparrow-shell聚合 parent、bom 与功能模块;不决定继承关系
以下模块由 shell 聚合
sparrow-parent开源生态版本 + 构建基线
↑ parent 继承
protocol · sparrow · authenticator内部功能组件,各自拥有发布版本

内部依赖仍需明确声明;构建与验证不依赖对外的组件版本清单。

平台交付 / 业务使用方

sparrow-bomparent = sparrow-parent
dependencyManagement = 公司组件版本清单
↑ 业务选择 parent 或 import 接入
passport-sparrow单模块或多模块业务应用
仅加入实际使用的 dependencies
protocol / core / auth starters版本由 BOM 统一选择

BOM 在本方案兼任“对外版本清单”和“可供业务继承的父 POM”。

三条线分别管理:modules 决定聚合范围,parent 决定配置继承,dependencies 决定实际依赖。BOM 中的版本管理条目不是一条实际 JAR 依赖边。
工件放什么何时更新
sparrow-parent经验证的 Spring 生态版本、JDK、编码、编译和测试插件规范开源基线、构建规则或必要修复变化时
内部功能组件自身实现、公开契约、实际使用的上游依赖功能、接口或依赖要求发生变化时
sparrow-bom各组件或组件组的版本、适合业务采用的兼容组合需要向业务交付新的版本组合时
业务工程根 POM业务坐标、模块列表及本工程必要的装配信息业务工程结构或业务版本变化时

Parent 相对稳定,并不意味着永久冻结。平台组仍需验证开源生态的兼容关系并维护基线;新的 parent 发布后,旧组件不会自动改变自己的构建历史。

STEP 02按组织分层:自产 BOM 交付给下游

这里的“上游”和“下游”是协作关系。社区提供开源生态的基础 parent 或依赖 BOM;公司平台组将经过验证的生态版本和构建要求沉淀到 sparrow-parent,生产自己的功能组件,再通过 sparrow-bom 向业务交付。

同一组织的组件生产者不继承或导入自己产出的对外 BOM。它们与 BOM 共同继承 sparrow-parent。因此,BOM 可以是下游业务的父 POM,却不是本组织内部 A/B/C 的父 POM。这里的“组织”按组件产品线的生产侧与消费侧划分:同一公司内的业务团队也可以是平台的下游。规则不只由仓库名、目录位置或行政归属决定。

一个组织的交付结果,可以成为下一个组织的输入

公司平台组的 sparrow-bom 对本组织是产物,对业务部门是上游基线。业务部门直接使用它即可;只有业务部门本身也要向新的下游交付一组可复用组件时,才需要考虑自己的版本清单。

以 C → B → A 为例:依赖升级与父配置升级分开

箭头表示“使用”:C 使用 B,B 使用 A。若三者都继承同一个对外 BOM,A 发版后更新 BOM,团队再要求所有组件切换到这个新父版本,就会把 B、C 带入新一轮 POM 更新和发布。即使它们的功能没有变化,也可能被统一版本策略牵动。

变化A/B/C 共同继承自产 BOMA/B/C 继承稳定 parent
A 发布兼容修复一旦同步新的 BOM 父版本,B/C 的 POM 也会变化;统一项目版本会进一步放大发布范围A 可以独立发布;B/C 是否采用新 A,按实际需求与兼容性决定
B 开始调用 A 的新接口B 的真实依赖变化与 BOM 父版本变化混在一起B 明确更新 A 的依赖版本并发布;C 是否需要修改取决于 B 的兼容性
对外推荐新的 A/B/C 组合产品清单同时成为内部父配置,容易产生“改清单 → 改组件 → 再改清单”的往返BOM 汇总已验证版本;稳定 parent 和无变化组件不必跟发

这种“循环更新”是发布流程耦合,不意味着 Maven 每次都会强制所有模块升级。对于破坏性 API 变化,必要的 B/C 适配仍然要做;架构分层消除的是额外的版本联动,而非真实依赖关系。

STEP 03把“循环”说准确

BOM 在 dependencyManagement 中管理 protocol,而 protocol 将该 BOM 作为 parent,这两项配置本身不构成 Maven 循环依赖。普通的版本管理条目不会要求 Maven 为构建 BOM 而先解析或构建 protocol。

情况判断
BOM 管理 protocol 版本,protocol 继承 BOM语法合法;在当前组织中容易产生版本与发布职责耦合
A 的 parent 是 B,B 的 parent 又是 A真正的父模型循环
两个 BOM 相互 import,或父 POM P 导入 BOM B,而 B 又以 P 为 parent可能形成模型解析循环,应避免
父 POM 在普通 dependencies 中依赖自己的子组件子组件继承后可能形成自依赖或构建依赖环

本方案禁止内部组件继承或导入对外 BOM,是为了切断“构建组件要先更新对外清单”的治理耦合。同时规定 sparrow-parent 不反向导入 sparrow-bom,保持模型关系单向。

官方说明:仅写在 dependencyManagement / pluginManagement 中的条目不改变 Reactor 构建排序。Maven · Reactor Sorting

STEP 04Parent 与 import,到底带来了什么?

选择 parent,表示接受一套可继承的工程配置;选择 import,表示只接入依赖版本管理。业务已有自己的父 POM 时,后者尤其有用。

比较项BOM 作为 parentBOM 通过 import 引入
声明位置<parent>dependencyManagement,type=pom + scope=import
数量一个直接 parent可导入多个 BOM,需要明确冲突优先级
依赖版本管理继承导入有效的管理清单,包含 BOM 继承所得的管理条目
普通 properties继承,可供子项目使用不会成为使用方自己的属性
构建插件与 pluginManagement按 Maven 继承规则获得不导入
普通 dependencies会继承,可能增加实际依赖不导入
业务 groupId / version未声明时可能继承,业务应明确填写自己的坐标不受 BOM 影响
是否自动引入全部组件dependencyManagement 不会自动添加依赖同样不会,仍需按需声明 dependencies
典型使用方接受公司完整构建规范的新业务项目已有父 POM、只需公司组件版本组合的业务项目
依据:Maven POM 继承、Importing Dependencies。Spring Boot 官方也明确:导入依赖 BOM 不会带入插件管理。
属性覆盖,不要混为一谈

继承链上以属性管理的版本,可由子项目按规则覆盖。纯 import 不会导入 BOM 的属性,不能假定在业务 POM 写同名属性就能覆盖导入结果;需要覆盖时,显式声明本项目的 dependencyManagement 条目,并检查有效 POM。父层再 import 的第三方 BOM 也有这个边界。

配置了插件版本,不等于执行了插件

pluginManagement 提供插件版本与默认配置。Compiler、Surefire 等默认生命周期插件会采用相应管理配置;Enforcer 等额外检查,还需要声明插件并绑定执行。导入 Spring 依赖 BOM 后,应由 sparrow-parent 另行管理构建插件。

STEP 05业务项目选择接入方式

对 passport-sparrow 这样的业务项目,平台提供一个入口、两种接法。切换下面的选项,查看各自保留的控制权。

继承公司 BOM,一次接入版本与规范

业务 POM 的 parent 指向 sparrow-bom。由于 BOM 继承 sparrow-parent,业务沿继承链获得公共构建配置和版本管理。业务只需声明自身坐标与实际使用的依赖。

获得组件版本获得构建规范无需部门级父 POM
业务接入 · parent 关键片段
<parent>
  <groupId>com.sparrowzoo</groupId>
  <artifactId>sparrow-bom</artifactId>
  <version>1.2.0</version>
  <relativePath/>
</parent>
<groupId>com.example.passport</groupId>
<artifactId>passport-sparrow</artifactId>
<version>1.0.0</version>

适合接受公司统一工程规范的业务。BOM 升级可能同时更新组件组合,以及它选择的 parent 基线,平台应说明这两类变化。

STEP 06多模块业务,不必再造一层部门标准

多模块是代码组织方式,不意味着业务部门需要另行建设、发布和维护一套公共 parent 或 BOM。最直接的做法是:工程根 POM 只声明模块列表,每个业务子模块直接继承公司 sparrow-bom。

组织方式适合的需求需要理解的边界
根只聚合,子模块直接继承公司 BOM尽量少一层继承;所有模块直接采用公司规范根 POM 的 properties / dependencyManagement 不会自动传给子模块;BOM 版本、业务版本和兄弟模块版本需协调
根继承公司 BOM,子模块继承工程根希望本工程只写一次 BOM 版本,并共享业务级配置这个根 POM 技术上是 parent,但不是额外建设一套部门级公共 Parent/BOM

两种方式都合法。若子模块以业务根作为 parent,并把子 JAR 发布给其他工程使用,该根 POM 也必须能从仓库解析。不能把“无需独立的部门级父配置产品”理解成“任何业务父 POM 都无需发布”。

STEP 07让三种版本按各自节奏演进

各组件拥有自己的版本;BOM 使用专门的组件版本属性来记录组合。不要把所有组件都绑定到一个 sparrow_version,也不要用 ${project.version} 表达 BOM 中全部组件的版本。

版本组合演示 示意版本 · 非已发布清单

工件原版本本次发布后业务采用情况
sparrow-parent1.0.01.0.0保持原基线
sparrow-protocol1.0.51.0.6BOM 仍选 1.0.5
sparrow1.0.71.0.7无需跟发
认证组件组1.1.21.1.2无需跟发
sparrow-bom1.2.01.2.0业务保持原组合
组件可以先发布,BOM 不必立即跟发。 新 protocol 继续继承原 parent。需要向业务推荐这次变化时,再验证兼容性并更新 BOM。
01 / BUILD构建、验证变化组件
02 / RELEASE发布组件独立版本
03 / VERIFY验证跨组件兼容组合
04 / DELIVER发布 BOM,业务按需采用
BOM 更新仍然有成本,但不再要求全套组件陪跑

要让业务通过统一入口选到新 protocol,版本清单仍需更新。收益是稳定 parent 和无变化的组件不必重发。若协议发生不兼容变更,相关实现与调用方仍需协同升级;独立版本不能消除真实的接口耦合。

STEP 08POM 示例:从平台到业务

下面的完整 POM 用于说明职责和继承关系。公司组件版本均为示意,不代表已发布工件;Spring Boot 3.5.0、Java 18 沿用当前讨论基线,不构成版本升级建议。示例尚未替换工程中的任何 POM。

01 · 平台聚合根:只组织构建POM / XML
sparrow-shell/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sparrowzoo</groupId>
  <artifactId>sparrow-shell</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <modules>
    <module>sparrow-parent</module>
    <module>sparrow-bom</module>
    <module>sparrow-protocol</module>
    <module>sparrow</module>
    <module>sparrow-authenticator/authenticator-core</module>
  </modules>
</project>
  • 示例只列讨论中的关键模块;实际迁移应保留所有需要聚合构建的现有模块。
  • 聚合根不承担公共继承职责,内部组件明确继承 sparrow-parent;聚合根自身版本不会决定被聚合组件的版本。
02 · 稳定 Parent:开源生态与构建基线POM / XML
sparrow-shell/sparrow-parent/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sparrowzoo</groupId>
  <artifactId>sparrow-parent</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <properties>
    <java.version>18</java.version>
    <maven.compiler.release>${java.version}</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-boot.version>3.5.0</spring-boot.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.13.0</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.5.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
  • 架构示例,版本号不是版本升级或兼容性背书;JDK 18 沿用讨论中的现有基线,实际按平台验证结果选择。
  • 导入 spring-boot-dependencies 只获得依赖版本管理,不等于继承 spring-boot-starter-parent,也不带入它的构建插件配置。
  • pluginManagement 提供插件版本与默认配置;默认生命周期已绑定的 compiler/surefire 会采用这些配置,其他未绑定插件需要显式声明或 execution。
  • 未加入仓库私有发布、签名、固定相对路径规则,避免这些平台生产侧配置被业务直接继承。
  • 不管理 Sparrow 自产组件的发布版本,也不导入 sparrow-bom。
03 · 协议组件:声明自身版本POM / XML
sparrow-shell/sparrow-protocol/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-parent</artifactId>
    <version>1.0.0</version>
    <relativePath>../sparrow-parent/pom.xml</relativePath>
  </parent>
  <artifactId>sparrow-protocol</artifactId>
  <version>1.0.5</version>
</project>
  • 组件独立声明发布版本,父版本 1.0.0 保持稳定。
  • 完整的最小 POM,用于说明版本边界;实际迁移须保留模块现有且必要的依赖、插件。
04 · 核心组件:明确内部依赖版本POM / XML
sparrow-shell/sparrow/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-parent</artifactId>
    <version>1.0.0</version>
    <relativePath>../sparrow-parent/pom.xml</relativePath>
  </parent>
  <artifactId>sparrow</artifactId>
  <version>1.0.7</version>
  <dependencies>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>sparrow-protocol</artifactId>
      <version>1.0.5</version>
    </dependency>
  </dependencies>
</project>
  • 平台生产者显式声明实际使用的内部依赖版本;不反向导入对外发行清单 sparrow-bom。
  • 这不是现有 sparrow 模块全部依赖的替换清单。
05 · 认证组件:独立于协议与核心发版POM / XML
sparrow-shell/sparrow-authenticator/authenticator-core/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-parent</artifactId>
    <version>1.0.0</version>
    <relativePath>../../sparrow-parent/pom.xml</relativePath>
  </parent>
  <artifactId>authenticator-core</artifactId>
  <version>1.1.2</version>
  <dependencies>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>sparrow-protocol</artifactId>
      <version>1.0.5</version>
    </dependency>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>sparrow</artifactId>
      <version>1.0.7</version>
    </dependency>
  </dependencies>
</project>
  • 认证组件可按发布组统一使用 1.1.2,且独立于 core 与 protocol。
  • 只展示组件关系,实际认证第三方依赖和运行时装配必须保留。
06 · 对外 BOM:parent 明确指向 sparrow-parentPOM / XML
sparrow-shell/sparrow-bom/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-parent</artifactId>
    <version>1.0.0</version>
    <relativePath>../sparrow-parent/pom.xml</relativePath>
  </parent>
  <artifactId>sparrow-bom</artifactId>
  <version>1.2.0</version>
  <packaging>pom</packaging>
  <properties>
    <sparrow.protocol.version>1.0.5</sparrow.protocol.version>
    <sparrow.core.version>1.0.7</sparrow.core.version>
    <sparrow.authenticator.version>1.1.2</sparrow.authenticator.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.sparrowzoo</groupId>
        <artifactId>sparrow-protocol</artifactId>
        <version>${sparrow.protocol.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sparrowzoo</groupId>
        <artifactId>sparrow</artifactId>
        <version>${sparrow.core.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sparrowzoo</groupId>
        <artifactId>authenticator-core</artifactId>
        <version>${sparrow.authenticator.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sparrowzoo</groupId>
        <artifactId>authenticator-monolithic-starter</artifactId>
        <version>${sparrow.authenticator.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
  • 这是有意采用的双用途 POM:业务 parent 入口,同时支持标准 BOM import;它继承稳定的 sparrow-parent。
  • 作为 parent 时可沿父链继承公共构建配置;作为 import 时只取得有效 dependencyManagement,包含父链继承得到的第三方依赖版本管理。
  • dependencyManagement 是版本规则,不会自动引入这些 JAR,也不要求这些 JAR 在发布该 POM 之前存在。
  • 需要验证组件之间的兼容性后再发布这个组合;示例中的不同版本号只说明可独立版本化。
  • 普通 dependencies 保持为空,避免所有业务消费者被强制引入整套框架。
07 · 业务根:采用公司基线并聚合模块POM / XML
passport-sparrow/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-bom</artifactId>
    <version>1.2.0</version>
    <relativePath/>
  </parent>
  <groupId>com.example.passport</groupId>
  <artifactId>passport-sparrow</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <modules>
    <module>passport-api</module>
    <module>passport-service</module>
    <module>passport-web</module>
  </modules>
</project>
  • relativePath 为空明确通过仓库解析公司级父 POM。
  • 业务显式声明自己的 groupId/version,防止继承平台坐标或把业务版本绑定到 BOM 版本。
  • 多模块只要求根 POM 聚合 modules,不要求部门额外维护和发布一套通用 parent 或 BOM。
  • 子模块是否继承根 POM由项目决定;仅列入 modules 并不会自动继承根 POM。
  • 以下 direct-bom 与 localroot 示例是单个子模块的替代写法,可按一致的项目规范选择。
08 · 业务子模块:直接继承公司 BOMPOM / XML
passport-sparrow/passport-api/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.sparrowzoo</groupId>
    <artifactId>sparrow-bom</artifactId>
    <version>1.2.0</version>
    <relativePath/>
  </parent>
  <groupId>com.example.passport</groupId>
  <artifactId>passport-api</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>sparrow-protocol</artifactId>
    </dependency>
  </dependencies>
</project>
  • 各子模块直接继承公司 BOM,根 POM 仅负责聚合也是合法结构。
  • 每个子模块都要显式声明业务 groupId/version,也需分别维护父 BOM 版本。
  • 如果 passport-web 依赖 passport-api,这种结构仍须明确该业务内部依赖的版本;聚合本身不提供版本管理。
09 · 可选写法:子模块继承本工程根 POMPOM / XML
passport-sparrow/passport-api/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.example.passport</groupId>
    <artifactId>passport-sparrow</artifactId>
    <version>1.0.0</version>
    <relativePath>../pom.xml</relativePath>
  </parent>
  <artifactId>passport-api</artifactId>
  <dependencies>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>sparrow-protocol</artifactId>
    </dependency>
  </dependencies>
</project>
  • 可选常见写法:业务根 POM 同时聚合并作为本项目子模块的父 POM;由根集中选择公司 BOM 版本。
  • 这是项目已有根 POM 的用途,不是要求业务部门再建一个通用 parent 产品或 BOM 产品。
  • 子模块继承的是根 POM 的业务版本 1.0.0,不是公司 BOM 的 1.2.0。
10 · 已有 parent:通过 import 接入POM / XML
passport-sparrow-import/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.0</version>
    <relativePath/>
  </parent>
  <groupId>com.example.passport</groupId>
  <artifactId>passport-sparrow</artifactId>
  <version>1.0.0</version>
  <properties>
    <java.version>18</java.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.sparrowzoo</groupId>
        <artifactId>sparrow-bom</artifactId>
        <version>1.2.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.sparrowzoo</groupId>
      <artifactId>authenticator-monolithic-starter</artifactId>
    </dependency>
  </dependencies>
</project>
  • 已有必须保留的父 POM 时,用 import 获取平台组件版本;一个项目只能有一个直接 parent。
  • 这里 java.version 是业务自己声明的属性,不是从 sparrow-bom import 过来的。
  • 此例的构建约定来自 Spring Boot parent;sparrow-parent 的插件配置和普通属性不会通过 BOM import 导入。
  • 父 POM 或其他 BOM 与 Sparrow 管理相同坐标时应检查 effective-pom 与 dependency:tree;示例刻意让 Boot 版本一致,不能据此断言不同版本可兼容。
生产构建还应明确启用哪些检查

把测试、依赖收敛等质量检查真正绑定到生命周期;不要默认跳过测试。内部库只生成普通 JAR,Spring Boot 的 repackage 由业务可执行模块按需启用。签名、仓库部署等平台发布动作宜放入显式发布配置,避免业务继承后被意外执行。

STEP 09这套分工带来的收益

01 / RELEASE

发布范围与变化范围一致

协议、核心、认证按实际变化发布,BOM 独立交付组合,减少无变化工件的重复发版。

02 / OWNERSHIP

平台与业务各自承担清晰职责

平台组验证基线和组件兼容性,业务部门选定组合并实现业务,不必重复维护公共版本标准。

03 / ADOPTION

统一接入,也保留迁移空间

新业务继承公司 BOM;已有工程可以先 import 接入,保留现有父配置和构建流程。

04 / TRACEABILITY

组合可追溯,升级可验证

固定的组件坐标让每次组合变化可比较。业务可以明确选择旧 BOM 或新 BOM,并验证自己的兼容性。

  • 稳定基线:parent 管第三方生态和构建规范,不反向导入自家的业务 BOM。
  • 版本独立:组件声明自身版本;BOM 通过专用属性管理组件或组件组,不绑定业务自身版本。
  • 按需依赖:普通 dependencies 只声明真正使用的库,避免公共父 POM 强制引入一整套业务组件。
  • 先看最终结果:升级或覆盖版本后,检查 mvn help:effective-pom 与 mvn dependency:tree,再运行相应测试。

DESIGN DECISION

内部面向基线,产物交付下游。

sparrow-bom 与内部 A/B/C 共同继承 sparrow-parent;下游业务再继承或导入 sparrow-bom。同一个组织不把自己的对外组件清单作为组件生产的父配置,减少“改清单、改组件、再改清单”的更新联动。

多模块工程只需要合适的聚合与继承组织,不需要因此再建立一套部门级 Parent/BOM。版本组合仍要维护,兼容性仍要验证;通过明确职责,让每次变化只触及真正需要变化的部分。

04 /

官方依据与阅读

下列文档支持 Maven 机制的说明;“平台生产者继承 parent、业务使用公司 BOM”的分工,是结合本项目背景给出的架构建议。文档核对日期:2026-09-22。

  1. [01]
    Maven · Introduction to the Dependency Mechanism ↗

    dependencyManagement、import、BOM,以及管理依赖和实际引入依赖的区别。

  2. [02]
    Maven · POM Reference ↗

    父 POM 继承、聚合、项目坐标、插件配置与 pluginManagement。

  3. [03]
    Maven · Guide to Working with Multiple Modules ↗

    Reactor 与多模块构建排序;版本管理声明不等于实际构建依赖。

  4. [04]
    Spring Boot · Using the Maven Plugin ↗

    继承 parent 与导入 dependencies BOM 的差异,以及版本覆盖的边界。

  5. [05]
    Maven · Introduction to the Build Lifecycle ↗

    packaging 与生命周期的默认插件目标绑定。