一、分模块设计与开发
1. 分模块设计
1.1 为什么需要分模块设计
将一个大项目拆分为若干个子模块,显著提升项目的可管理性、维护性、扩展性,同时便于模块间相互引用和资源共享 。
1.2 拆分策略
策略一:按功能模块拆分
- 将项目按业务功能划分为独立模块,如:
- 公共组件模块
- 商品模块
- 搜索模块
- 购物车模块
- 订单模块
- 优点:业务边界清晰,团队可独立开发各自功能模块
策略二:按技术层次拆分
- 采用传统三层架构模式:
- api(或interface):存放接口和数据模型(DTO/VO/Entity)
- service:业务逻辑实现层
- dao(或repository):数据访问层
- web(或controller):用户接口层
- 优点:代码结构清晰,便于分层维护
策略三:功能模块+技术层次组合拆分
- 例如:
- order-service:包含订单模块的控制层、业务层、数据层
- user-service:包含用户模块的控制层、业务层、数据层
- common-utils:通用工具模块
- 优点:兼顾业务隔离和技术分层,适合大型复杂项目
1.3 实操步骤
核心原则 :先设计模块功能,再编码 (不可先开发完整工程再拆分)
示例拆分:
- 创建
tlias-pojo模块,存放实体类 - 创建
tlias-utils模块,存放工具类 - 各业务模块(如订单、用户)按需引入这些通用模块
1.4 注意事项
- 模块命名规范:采用
项目名-模块名或项目名-模块名-层级格式(如order-service、user-dao) - 模块依赖关系:需设计清晰的依赖方向,避免循环依赖
- 先设计后编码:模块划分应与项目架构设计同步,而非后期拆分
- 通用组件模块化:将工具类、实体类等通用代码独立为模块,便于复用
2. 继承与聚合
2.1 继承机制
2.1.1 概念
继承描述父子工程间的关系,子工程继承父工程的配置信息(如依赖版本、插件配置) 。
2.1.2 作用
- 简化依赖配置:避免重复声明相同依赖
- 统一管理依赖版本:确保所有子模块使用一致版本
- 集中配置公共插件:如代码检查、编译参数等
2.1.3 实现方式
在子工程的pom.xml中通过<parent>标签声明继承关系:
xml
<parent>
<groupId>com.itheima</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../tlias-parent/pom.xml</relativePath>
</parent>
2.1.4 父工程配置
父工程(tlias-parent)的pom.xml关键配置:
xml
<groupId>com.itheima</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.10</version>
<relativePath/>
</parent>
<properties>
<lombok.version>1.18.30</lombok.version>
<jjwt.version>0.9.1</jjwt.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- JWT依赖版本管理 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2.1.5 继承规则
- groupId继承:子工程可省略groupId,自动继承父工程
- 版本冲突:若父子工程声明相同依赖的不同版本,以子工程配置为准
- relativePath:指定父工程pom的相对路径,若不指定则从本地仓库/远程仓库查找
2.2 版本锁定
2.2.1 实现方式
通过父工程的<dependencyManagement>标签统一管理依赖版本 :
xml
<!-- 父工程pom.xml -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
子工程声明依赖时无需指定版本:
xml
<!-- 子工程pom.xml -->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2.2.2 依赖管理对比
| 标签 | 作用 | 子工程是否需要声明依赖 | 子工程是否需要指定版本 |
|---|---|---|---|
<dependencies> |
直接引入依赖 | 否(自动继承) | 否 |
<dependencyManagement> |
统一管理依赖版本 | 是 | 否(自动使用父工程版本) |
2.3 聚合机制
2.3.1 概念
聚合工程是一个不包含业务功能的"空"工程,通过<modules>标签声明包含的子模块,实现多模块统一构建 。
2.3.2 作用
- 一键构建 :在聚合工程目录下执行
mvn clean install,可自动构建所有子模块 - 自动构建顺序 :根据模块间依赖关系自动排序,与
<modules>标签中声明顺序无关 - 统一管理:便于团队协作和版本控制
2.3.3 实现方式
在聚合工程的pom.xml中通过<modules>标签声明子模块:
xml
<project>
<groupId>com.itheima</groupId>
<artifactId>tlias聚合</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>pojo</module>
<module>utils</module>
<module>service</module>
<module>web</module>
</modules>
</project>
2.3.4 继承与聚合的区别
| 特性 | 继承 | 聚合 |
|---|---|---|
| 核心目的 | 简化配置、统一依赖版本 | 统一构建、管理子模块 |
| 声明位置 | 子工程中的<parent>标签 |
父工程中的<modules>标签 |
| 配置文件 | 父工程的pom.xml |
父工程的pom.xml |
| 打包类型 | 通常为pom |
必须为pom |
| 依赖关系 | 子工程依赖父工程 | 父工程不依赖子工程 |
3. 私服(Nexus)
3.1 私服简介
私服是一种架设在企业内网的Maven仓库服务,主要解决以下问题:
- 团队内部构件共享
- 避免频繁访问中央仓库
- 加速依赖下载
- 管理企业内部开发的构件
3.2 Nexus仓库类型
| 仓库类型 | 用途 | 特点 | 示例 |
|---|---|---|---|
| Proxy | 代理中央仓库 | 缓存依赖,加速下载 | Maven Central代理 |
| Hosted | 存储私有构件 | 上传内部开发的JAR/WAR | Releases/Snapshots |
| Group | 聚合多个仓库 | 提供统一入口,优先级可配置 | 企业公共仓库组 |
3.3 配置Maven使用私服
3.3.1 settings.xml配置
**全局配置文件settings.xml**需包含以下关键配置:
xml
<settings>
<!-- 1. 仓库镜像配置 -->
<mirrors>
<mirror>
<id>nexus-mirror</id>
<mirrorOf>*,!jcenter</mirrorOf> <!-- 排除其他镜像 -->
<url>http://私服IP:8081/repository/public/</url>
<name>Nexus Public Mirror</name>
</mirror>
</mirrors>
<!-- 2. 认证信息配置 -->
<servers>
<server>
<id>releases</id>
<username>admin</username>
<password>password</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>password</password>
</server>
</servers>
<!-- 3. 本地仓库路径 -->
<localRepository>${user.home}/.m2/repository</localRepository>
</settings>
关键点:
<mirrorOf>的*表示匹配所有仓库,!jcenter表示排除jcenter仓库<server>的id必须与<mirror>或<repository>的id一致,才能正确认证
3.3.2 pom.xml配置
在项目pom.xml中配置<distributionManagement>声明发布仓库:
xml
<distributionManagement>
<!-- 正式版本发布仓库 -->
<repository>
<id>releases</id>
<url>http://私服IP:8081/repository/maven-releases/</url>
</repository>
<!-- 快照版本发布仓库 -->
<snapshotRepository>
<id>snapshots</id>
<url>http://私服IP:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
关键点:
<id>需与settings.xml中<server>的id匹配- 正式版本(
-SNAPSHOT后缀)自动发布到Snapshots仓库,稳定版本发布到Releases仓库
3.4 依赖上传与下载
3.4.1 依赖发布命令
发布到Releases仓库:
bash
mvn clean deploy -DskipTests
发布到Snapshots仓库:
bash
mvn clean deploy -DskipTests -DaltDeploymentRepository=snapshots::default::http://私服IP:8081/repository/maven-snapshots/
手动上传SNAPSHOT:
bash
mvn deploy:deploy-file \
-DgroupId=com.aaa \
-DartifactId=bbb \
-Dversion=0.0.1-SNAPSHOT \
-Dpackaging=jar \
-Dfile=bbb-0.0.1-SNAPSHOT.jar \
-Durl=http://私服IP:8081/repository/maven-snapshots/ \
-DrepositoryId=snapshots
3.4.2 依赖查找顺序
Maven依赖解析遵循以下优先级 :
- 本地仓库:检查本地缓存
- 私服仓库:通过镜像或直接配置的仓库
- 中央仓库:最后从Maven Central下载
3.5 版本管理策略
3.5.1 项目版本类型
| 版本类型 | 用途 | 存储仓库 | 特点 |
|---|---|---|---|
| SNAPSHOT | 开发中版本 | Snapshots仓库 | 支持每日构建更新 |
| RELEASE | 稳定发布版本 | Releases仓库 | 不可更新,永久保留 |
3.5.2 版本控制建议
- 开发阶段 :使用
-SNAPSHOT后缀版本,便于快速迭代 - 正式发布 :移除
-SNAPSHOT后缀,确保版本唯一性 - 版本回滚:在Nexus中保留历史版本,便于问题排查
3.6 Nexus权限管理
3.6.1 匿名访问设置
禁用匿名访问(推荐):
- 登录Nexus管理界面
- 进入
Security >Anonymous Access - 取消勾选
Allow anonymous users to access the server
开启匿名访问(仅限特殊场景):
- 勾选
Allow anonymous users to access the server - 适用于仅需读取权限的场景(如CI/CD流水线)
3.6.2 用户权限管理
- 角色划分 :
- 开发者:仅需读取权限
- 运维/部署:需读写权限
- 管理员:完整管理权限
- 权限配置 :
- 在Nexus中为不同用户组分配对应仓库的权限
- 通过
<server>标签在settings.xml中为CI/CD工具配置专用账号
3.7 私服使用场景
3.7.1 企业级应用
- 内部组件共享:如通用工具类、企业级框架等
- 版本控制:统一管理依赖版本,避免版本冲突
- 网络隔离环境:如内网开发环境,无法访问外网时使用
- 加速构建:减少对中央仓库的访问,提升构建速度
3.7.2 团队协作
- 统一依赖版本:确保团队成员使用一致依赖
- 内部依赖管理:如自定义 starter、通用组件等
- 安全管控:限制高危依赖版本下载,确保代码安全
四、补充知识
4.1 Maven多环境配置
通过<profile>实现不同环境的配置切换:
xml
<!-- settings.xml -->
<profiles>
<profile>
<id>dev</id>
<激活条件>
<activeByDefault>true</activeByDefault>
</激活条件>
<properties>
<env>dev</env>
</properties>
<repositories>
<repository>
<id>public</id>
<url>http://私服IP:8081/repository/public/</url>
</repository>
</repositories>
</profile>
<profile>
<id>prod</id>
<激活条件>
<activeByDefault>true</activeByDefault>
</激活条件>
<properties>
<env>prod</env>
</properties>
<repositories>
<repository>
<id>prod-repo</id>
<url>http://prod-nexus:8081/repository/prod/</url>
</repository>
</repositories>
</profile>
</profiles>
激活特定profile:
bash
mvn clean install -Pprod
4.2 模块间依赖声明
在子模块pom.xml中声明依赖:
xml
<dependencies>
<!-- 依赖其他子模块 -->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 依赖第三方库 -->
<dependency>
<groupId>org projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
4.3 构建命令详解
常用Maven命令:
bash
# 清理项目
mvn clean
# 编译项目
mvn compile
# 编译并打包
mvn package
# 编译、测试、打包并安装到本地仓库
mvn install
# 生成文档
mvn site
# 部署到远程仓库(如Nexus)
mvn deploy
4.4 Nexus仓库管理实践
企业级Nexus仓库管理建议:
- 仓库命名规范 :采用
环境-用途格式(如dev-proxy、prod-release) - 权限隔离:为不同团队/项目创建独立仓库,避免相互影响
- 定期清理:清理过期SNAPSHOT版本,释放存储空间
- 镜像配置:为常用中央仓库创建Proxy镜像,加速依赖下载
- 版本准入:制定依赖版本准入规则,避免使用高危版本
4.5 构建优化技巧
提升Maven构建效率的方法:
- 增量构建 :利用
-U参数强制更新SNAPSHOT依赖 - 并行构建 :使用
-T参数开启多线程构建(如-T4表示4线程) - 跳过测试 :使用
-DskipTests跳过测试阶段 - 缓存依赖:定期清理本地仓库,避免缓存冲突
- 构建缓存 :使用
maven插件缓存已编译代码
4.6 Nexus安全最佳实践
Nexus安全配置建议:
- 禁用匿名访问:强制所有访问需认证
- 定期备份:备份Nexus数据,防止数据丢失
- 访问日志:开启访问日志,便于审计和问题排查
- 版本限制:禁止下载已知存在漏洞的依赖版本
- 账号隔离:为CI/CD工具创建专用账号,限制权限
4.7 Maven项目结构示例
典型Maven多模块项目结构:
my-project/
├── pom.xml # 聚合工程pom
├── parent/
│ ├── pom.xml # 父工程pom
├── common/
│ ├── src/
│ └── pom.xml
├── service/
│ ├── src/
│ └── pom.xml
└── web/
├── src/
└── pom.xml
关键点:
- 父工程负责依赖管理和版本锁定
- 聚合工程负责统一构建
- 子模块按功能或层次划分
4.8 Maven项目生命周期
Maven项目生命周期阶段:
validate -> initialize -> generate-sources -> process-sources
-> generate-resources -> process-resources -> compile
-> process-classes -> generate-test-resources -> process-test-resources
-> test-compile -> process-test-classes -> test
-> prepare-package -> package -> pre-integrate -> integrate
-> post-integrate -> verify -> install -> deploy
常用阶段:
package:编译并打包项目install:安装到本地仓库deploy:部署到远程仓库(如Nexus)
4.9 Maven插件管理
插件配置示例:
xml
<!-- 在父工程pom.xml中统一管理插件 -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
子模块启用插件:
xml
<!-- 子模块pom.xml中启用插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
五、常见问题与解决方案
5.1 依赖冲突问题
现象:编译或运行时出现类冲突
解决方案:
- 使用
mvn dependency:tree分析依赖树 - 通过
<exclusion>排除冲突依赖 - 在父工程
<dependencyManagement>中统一版本
5.2 构建顺序问题
现象:模块间依赖关系导致构建失败
解决方案:
- 在聚合工程
<modules>标签中声明模块顺序 - 确保子模块pom.xml正确声明依赖关系
- 使用
<dependency>标签明确指定依赖范围
5.3 匿名访问问题
现象:构建时出现401未授权错误
解决方案:
- 在Nexus中开启匿名访问(临时方案)
- 在settings.xml中配置对应server认证
- 确保server id与mirror id一致
5.4 SNAPSHOT版本更新问题
现象:本地未获取到最新SNAPSHOT版本
解决方案:
- 使用
mvn clean install -U强制更新 - 检查Nexus中SNAPSHOT仓库是否开启自动更新
- 检查settings.xml中是否正确配置了镜像
六、面试高频考点
6.1 分模块设计优势
回答要点:
- 解耦:降低模块间依赖
- 复用:通用组件可跨模块/项目使用
- 可维护性:模块独立,修改不影响其他模块
- 团队协作:不同团队可并行开发不同模块
6.2 继承与聚合的区别
回答要点:
- 继承:子工程主动关联父工程,用于依赖管理和配置继承
- 聚合:父工程被动管理子模块,用于统一构建
- 继承通过
<parent>标签实现,聚合通过<modules>标签实现 - 继承可跨级(如父工程继承Spring Boot Parent),聚合只能管理直接子模块
6.3 私服的作用与配置
回答要点:
- 作用:内部构件共享、加速依赖下载、安全管控
- 配置:在settings.xml中配置mirror和server,在pom.xml中配置distributionManagement
- 仓库类型:Proxy代理中央仓库,Hosted存储内部构件,Group聚合多个仓库
- 版本管理:SNAPSHOT用于开发,RELEASE用于正式发布
6.4 Maven构建流程
回答要点:
- 分析项目结构
- 解析依赖关系
- 根据生命周期执行构建
- 处理插件配置
- 安装/部署构件
6.5 多模块项目构建技巧
回答要点:
- 使用聚合工程实现一键构建
- 通过
-pl参数指定构建特定模块(如-pl service,web) - 通过
-am参数构建指定模块及其依赖的模块 - 使用
-T参数开启多线程构建提升效率
七、总结
Maven高级特性是Java Web开发中的重要工具,掌握以下核心内容可显著提升项目开发效率:
分模块设计:根据业务功能或技术层次合理拆分模块,遵循"先设计后编码"原则
继承机制:通过父工程统一管理依赖版本和配置,简化子模块配置
聚合机制:通过聚合工程实现多模块统一构建,提升团队协作效率
私服应用:搭建Nexus私服管理内部构件,提升依赖下载速度和安全性
版本管理:区分SNAPSHOT和RELEASE版本,确保开发与生产环境一致性
权限控制:合理配置Nexus仓库权限,平衡安全与便利性