Maven多模块
Maven多模块项目是一种将一个大型项目分解为多个子模块的项目组织方式,每个子模块都是一个独立的Maven项目,但它们共同组成一个完整的系统。目前我参与的大厂内部的大型Java项目都是基于Maven多模块进行构建的,其优势在于:
- 代码组织结构清晰:按功能、层次等逻辑划分模块
- 重用性提高:模块可以在不同项目间共享
- 简化依赖管理:通过父POM统一管理依赖版本
- 一致性保障:确保各模块使用相同配置和依赖版本
- 灵活的发布策略:可以单独或整体发布模块。
基本概念
Maven多模块项目由一个父项目(Parent Project)和多个子模块(Sub-modules)组成:
- 父项目:不包含源代码,主要提供项目的整体配置和管理
- 子模块:实际功能模块,每个子模块都有自己的POM文件
通常,可以按照两种方式进行拆分:
- 按照结构进行拆分:
- ParentProject
- Sub-Modules-service
- Sub-Modules-controller
- Sub-Modules-dao
这种一般是传统的Web项目,整个项目构建成为一个应用。
- 按照业务进行拆分:
- ParentProject
- Sub-Modules-cpc
- Sub-Modules-cpm
- Sub-Modules-cpt
这种更多的常见于公司内部的大型Java后台服务项目,每个模块作为后端的服务进行构建与发布。
Maven多模块与DDD的关系
Maven多模块与DDD之间的关系是从 “逻辑设计” 到 “物理落地” 的递进关系。
DDD 通过 “限界上下文” 划分业务领域,每个上下文内的业务逻辑高度内聚,上下文间通过 “上下文映射”(如共享内核、防腐层)交互。
这种逻辑边界可直接映射为 Maven 的 “业务模块”:
- 每个限界上下文对应一个独立的 Maven 模块(如
order-domain
、user-domain
),模块内包含该上下文的领域模型(实体、聚合等)。 - 上下文间的依赖通过 Maven 模块的依赖关系体现(如
order-domain
依赖user-domain
的部分接口),避免跨上下文的直接代码耦合。
常用的六边形架构设计,将系统分为 “内部核心” 和 “外部依赖”,内部核心又可细分为 “领域层” 和 “应用层”,外部依赖通过 “适配器” 接入。这种分层可通过 Maven 多模块实现物理隔离。
因此上述规则需要通过物理结构固化,否则容易在开发中被破坏。而Maven多模块能够通过父子Pom管理实现这种约束。
一句话概括,即DDD 提供业务层面的 “逻辑边界”,六边形架构提供技术层面的 “依赖规则”,Maven 多模块将这些逻辑边界和规则通过 “物理模块” 固化落地,其最终目标是构建一个 “业务清晰、依赖可控、易于维护” 的系统 —— 业务逻辑不被技术细节干扰,模块间边界明确,可独立迭代。
父子Pom配置最佳实践
父POM使用<dependencyManagement>
统一管理依赖版本。父Pom在dependencyManagement
中需要指定依赖的版本。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>ParentProject</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<!-- 声明子模块 -->
<modules>
<module>Sub-Modules-cpc</module>
<module>Sub-Modules-cpm</module>
<module>Sub-Modules-cpt</module>
</modules>
<!-- 依赖管理,不会实际引入依赖 -->
<dependencyManagement>
<dependencies>
<!-- 共享的依赖版本定义 -->
</dependencies>
</dependencyManagement>
</project>
子Pom中只需要指定父Pom引入的依赖即可,而不用指定版本号。这样也就保证了各个子模块使用相同的配置与依赖版本,避免依赖冲突。
<project>
<modelVersion>4.0.0</modelVersion>
<!-- 引用父项目 -->
<parent>
<groupId>com.example</groupId>
<artifactId>ParentProject</artifactId>
<version>1.0.0</version>
</parent>
<!-- 仅定义artifactId,继承父项目的groupId和version -->
<artifactId>Sub-Modules-cpc</artifactId>
<dependencies>
<!-- 该模块特定的依赖 -->
</dependencies>
</project>
子模块可以单独成为发布项进行构建与部署。
同时也注意合理规划模块划分,保持低耦合高内聚。
构建命令:
# 构建整个项目
mvn clean install
# 构建特定模块
mvn clean install -pl Sub-Modules-cpc -am