📦 Maven进阶:从单模块到企业级私服架构实战
本文通过一个真实的团队开发故事,带你深入理解Maven的分模块开发、依赖冲突、聚合继承以及私服搭建等核心概念。
一、从一个开发困境说起
故事背景
想象一下这个场景:
张三负责开发ssm_crm项目,他写了一个通用的ssm_pojo模块,包含了所有的实体类。为了方便使用,他通过mvn install把模块安装到了本地仓库。
李四负责开发ssm_order项目,需要用到张三的ssm_pojo模块。按照Maven的依赖管理,他在pom.xml中添加了依赖:
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven_03_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
问题来了:李四的机器上并没有这个jar包,Maven从本地仓库找不到,编译报错!
解决方案
张三需要把模块分享给李四,有几种方式:
但在讲私服之前,我们先来看看Maven分模块开发会遇到的几个核心问题。
二、分模块开发设计
为什么需要分模块?
单体应用 分模块应用
┌─────────────┐ ┌─────────────────┐
│ │ │ maven_03_ssm │
│ 一个项目 │ → │ (业务层) │
│ 所有代码 │ ├─────────────────┤
│ │ │ maven_02_pojo │
└─────────────┘ │ (实体层) │
├─────────────────┤
│ maven_01_utils │
│ (工具层) │
└─────────────────┘
模块划分方式
| 按功能分 | 按业务功能拆分 | 用户模块、订单模块、商品模块 |
| 按层分 | 按技术层次拆分 | pojo、dao、service、controller |
模块间的依赖管理
当模块A依赖模块B时:
<!– 在模块A的pom.xml中引入模块B –>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven_02_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
重要提示:被依赖的模块必须先install到本地仓库!
# 进入模块B目录
mvn install
三、依赖冲突:隐藏的定时炸弹
故事续集
随着项目发展,模块越来越多,依赖关系变得越来越复杂:
maven_03_ssm
├── spring-context:5.2.10.RELEASE
├── spring-web:5.2.9.RELEASE ← 版本不一致!
├── maven_02_pojo
│ └── commons-logging:1.2
└── maven_01_utils
└── commons-logging:1.1 ← 版本冲突!
问题:当同一个jar包有多个不同版本时,就会发生依赖冲突!
依赖冲突解决规则
Maven解决依赖冲突有三条黄金法则:
| 1. 路径优先 | 层级越浅优先级越高 | A→B→C:1.0 和 A→C:2.0,选2.0 |
| 2. 声明优先 | 同层级时先声明的优先 | pom.xml中先写的生效 |
| 3. 后覆盖前 | 同版本时后面的覆盖前面的 | 在同一个pom中多次声明,后面的生效 |
解决方案
方案1:可选依赖(隐藏资源)
<!– 在提供方隐藏依赖 –>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<optional>true</optional> <!– 该依赖不会传递给使用者 –>
</dependency>
方案2:排除依赖(剔除不需要的)
<!– 在使用方排除特定依赖 –>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven_02_pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
四、聚合与继承:团队协作的基石
新的问题
随着模块越来越多,新问题出现了:
4.1 聚合工程:一键构建
聚合:创建一个父项目,统一管理所有子模块的构建。
<!– 聚合工程的pom.xml –>
<project>
<groupId>com.itheima</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <!– 打包方式必须为pom –>
<!– 聚合子模块 –>
<modules>
<module>../maven_02_pojo</module>
<module>../maven_03_dao</module>
<module>../maven_04_service</module>
<module>../maven_05_controller</module>
</modules>
</project>
效果:在父项目执行mvn clean install,所有子模块自动构建!
4.2 继承工程:统一配置
继承:子模块继承父模块的配置,避免重复。
步骤1:父工程配置
<!– 父工程pom.xml –>
<project>
<!– 统一管理依赖版本 –>
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<mysql.version>8.0.30</mysql.version>
</properties>
<!– 依赖管理:子模块可以选择性继承 –>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
步骤2:子工程继承
<!– 子工程pom.xml –>
<project>
<!– 指定父工程 –>
<parent>
<groupId>com.itheima</groupId>
<artifactId>maven_01_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../maven_01_parent/pom.xml</relativePath>
</parent>
<!– 只需指定groupId和version,不用写版本号 –>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<!– version从父工程继承,无需指定 –>
</dependency>
</dependencies>
</project>
4.3 聚合 vs 继承 对比
| 作用 | 快速构建项目 | 快速配置项目 |
| 配置位置 | 父模块中配置<modules> | 子模块中配置<parent> |
| 感知关系 | 父模块知道有哪些子模块 | 父模块不知道有哪些子模块 |
| pom类型 | packaging=pom | packaging=pom |
完美结合:可以在同一个pom中同时实现聚合和继承!
五、属性定义:让配置活起来
问题场景
当多个依赖使用相同版本时:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.10.RELEASE</version> <!– 重复的版本号 –>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version> <!– 到处都要改 –>
</dependency>
</dependencies>
解决方案:自定义属性
<project>
<!– 定义属性 –>
<properties>
<spring.version>5.2.10.RELEASE</spring.version>
<mysql.version>8.0.30</mysql.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version> <!– 引用属性 –>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</project>
好处:升级版本只需改一处!
扩展:让属性在资源文件中生效
<build>
<resources>
<!– 设置资源目录并开启过滤功能 –>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> <!– 开启${}解析 –>
</resource>
</resources>
</build>
然后在application.properties中就可以使用:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_db
jdbc.username=${db.username} <!– 可以引用pom中的属性 –>
jdbc.password=${db.password}
六、私服:团队资源共享中心
故事高潮
随着团队规模扩大,问题越来越突出:
- 张三:开发了通用工具类,要分享给全公司
- 李四:需要Oracle驱动,中央仓库没有
- 王五:下载Spring依赖太慢,每次都要等很久
解决方案:搭建Maven私服!
6.1 什么是私服?
私服是公司内部搭建的Maven资源服务器,相当于公司内部的中央仓库。

6.2 私服仓库分类
私服中有三类仓库:
| 宿主仓库(hosted) | 公司内部仓库 | 自主研发的jar包、第三方商业包(如Oracle驱动) |
| 代理仓库(proxy) | 代理远程仓库 | 从中央仓库下载的第三方jar包 |
| 仓库组(group) | 仓库集合 | 将多个仓库组合,对外提供统一访问入口 |
6.3 本地Maven配置私服
步骤1:配置私服访问权限(settings.xml)
<servers>
<!– 快照版仓库权限 –>
<server>
<id>itheima-snapshot</id>
<username>admin</username>
<password>admin</password>
</server>
<!– 发布版仓库权限 –>
<server>
<id>itheima-release</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
步骤2:配置私服镜像地址
<mirrors>
<mirror>
<!– 所有请求都走私服 –>
<id>nexus-public</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
步骤3:配置项目上传地址(pom.xml)
<distributionManagement>
<!– 快照版上传地址 –>
<snapshotRepository>
<id>itheima-snapshot</id>
<url>http://localhost:8081/repository/itheima-snapshot/</url>
</snapshotRepository>
<!– 发布版上传地址 –>
<repository>
<id>itheima-release</id>
<url>http://localhost:8081/repository/itheima-release/</url>
</repository>
</distributionManagement>
6.4 上传与下载
上传项目到私服:
mvn deploy
从私服下载:
项目正常添加依赖,Maven会自动从私服下载!
6.5 SNAPSHOT vs RELEASE
| SNAPSHOT(快照版) | 可重复覆盖,开发阶段使用 | 团队协作开发中 |
| RELEASE(发布版) | 不可修改,正式发布 | 项目上线后 |
七、总结:Maven进阶知识图谱
┌─────────────────────────────────────────────────┐
│ Maven进阶 │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 模块化开发 │ → │ 聚合与继承 │ │
│ │ • 功能划分 │ │ • 统一构建 │ │
│ │ • 分层架构 │ │ • 集中配置 │ │
│ └──────────────┘ │ • 版本控制 │ │
│ │ └──────────────────────┘ │
│ ▼ │ │
│ ┌──────────────┐ ▼ │
│ │ 依赖管理 │ ┌──────────────────────┐ │
│ │ • 路径优先 │ │ 私服平台 │ │
│ │ • 声明优先 │ │ • 中央仓库代理 │ │
│ │ • 版本覆盖 │ │ • 仓库集群 │ │
│ └──────────────┘ └──────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 统一配置 │ │ 协同开发 │ │
│ │ • 版本管理 │ │ • 资源共享 │ │
│ │ • 资源过滤 │ │ • 构建优化 │ │
│ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────┘
一句话总结
分模块是基础,聚合继承是效率,私服是团队协作的保障!
掌握了这些Maven进阶技能,你就能从一个单打独斗的开发者,成长为企业级项目的架构师!
附录:常用Maven命令速查表
| mvn clean | 清理target目录 | 重新构建前 |
| mvn compile | 编译源代码 | 检查语法错误 |
| mvn test | 运行测试 | 单元测试 |
| mvn package | 打包成jar/war | 生成部署包 |
| mvn install | 安装到本地仓库 | 供其他模块使用 |
| mvn deploy | 部署到私服 | 团队共享 |
| mvn site | 生成项目文档 | 项目报告 |
📝 写在最后:Maven不仅仅是一个构建工具,更是团队协作的基石。希望本文能帮助你从"会用"到"精通",在实际项目中游刃有余!

