Maven高级
分模块设计与开发
顾名思义指的就是我们在设计一个 Java 项目的时候,将一个 Java 项目拆分成多个模块进行开发
如果不分模块开发,将所有业务代码全部写在一个Java项目当中,随着项目业务的扩张,项目的管理和维护将会愈发困难
所以在项目设计阶段,就可以将一个大的项目拆成若干个独立的模块
拆分策略
比如一个商城系统就可以拆成多个小模块
- 策略一:按照功能模块拆分,比如:公共组件、商品模块、搜索模块、购物车模块、订单模块等
- 策略二:按层拆分,比如:公共组件、实体类、控制层、业务层、数据访问层
- 策略三:按照功能模块 + 层拆分

实现
此处按模块拆分进行演示
分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分
此处以演示为主,故将项目开发后进行拆分
在项目同目录下创建一个模块用于存放项目的实体类(创建普通Java模块即可):
将项目中的实体类存入其中:
给tlias-pojo模块导入实体类用到的依赖(这只是个普通的Java模块,需要指定依赖版本号,版本号应该与SpringBoot项目中相同):
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.2.10</version>
</dependency>
</dependencies>
|
在项目中导入tlias-pojo模块:
1
2
3
4
5
6
|
<!-- tlias-pojo 模块 -->
<dependency>
<groupId>com.yuanyu</groupId>
<artifactId>tlias-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
|
此时启动项目后发现依旧可以正常运行。同理,可以把其他模块拆分出去
继承与聚合
继承
刚刚学到了分模块开发的思路,但又有新的问题出现了,依赖的版本控制变得繁琐起来了
比如说,每个模块都使用了Lombok,现在需要换成新版Lombok使用,那就需要去各个模块中找到并修改Lombok的依赖版本,当模块数量多的时候就会非常麻烦
而Maven的继承解决的就是这个问题
可以再创建一个父工程 tlias-parent ,然后让上述的三个模块 tlias-pojo、tlias-utils、tlias-web-management 都来继承这个父工程
然后再将各个模块中都共有的依赖,都提取到父工程 tlias-parent中进行配置,只要子工程继承了父工程,依赖它也会继承下来,这样就无需在各个子工程中进行配置了
实现方式:
1
2
3
4
5
6
|
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<relativePath>....</relativePath>
</parent>
|
具体实现步骤
1.创建Maven模块tlias-parent,设置打包方式为pom,并删除模块里的src目录,并配置继承的工程
打包方式:
jar:普通模块打包,springboot项目基本都是jar包(内嵌tomcat运行)
war:普通web程序打包,需要部署在外部的tomcat服务器中运行
pom:父工程或聚合工程,该模块不写代码,仅进行依赖管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- tlias-web-management继承了下面这个工程,为了统一管理依赖版本,tlias-web-management又需要继承当前工程
但一个工程只能有一个父工程,所以在该工程中继承下方工程,再让tlias-web-management继承当前工程
这样就可以间接继承spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.10</version>
<!-- 配置父工程pom.xml文件的相对路径 -->
<!-- 不指定时默认会从本地仓库和远程仓库中查找 -->
<relativePath/>
</parent>
<groupId>com.yuanyu</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 设置打包方式为pom -->
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
|
2.让tlias-pojo、tlias-utils、tlias-web-management继承tlias-parent(此时子工程的<groupId>可以省略)
1
2
3
4
5
6
7
|
<parent>
<groupId>com.yuanyu</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 配置父工程pom.xml文件的相对路径 -->
<relativePath>../tlias-parent/pom.xml</relativePath>
</parent>
|
3.将共有的依赖提取到tlias-parent的pom.xml中,再删除子工程中的这些依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.2.10</version>
</dependency>
</dependencies>
|
若父子工程都配置了同一个依赖的不同版本,子工程以自己配置的为准(类似Java中的重写)
在实际项目中,子工程一般会创建在父工程内,这样看起来更直观
版本锁定
那么问题又来了,上述方法只解决了所有模块共有的依赖的版本控制,但有些依赖只有部分模块需要,其余模块不需要,这种情况就解决不了了
有人可能会觉得将所有依赖都放在父工程不就好了,但如果将所有的依赖全部放到了父工程,当别人只想使用某个子模块时,就会把所有的依赖全部继承过来,造成严重的性能与资源浪费
为了解决这种情况,可以在父工程的pom.xml文件中使用<dependencyManagement>来统一管理依赖版本
父工程中:
1
2
3
4
5
6
7
8
9
10
|
<dependencyManagement>
<dependencies>
<!--JWT 令牌-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
</dependencyManagement>
|
需要此依赖的子工程中正常导入,但不用指定版本号:
1
2
3
4
5
6
|
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
|
这也就是为什么在springboot项目中很多时候,引入依赖坐标,都不需要指定依赖的版本 <version>
还可以在此基础上进一步优化代码
可以通过在父工程的pom.xml中的<properties>标签中设置自定义属性统一管理版本号

聚合
当项目开发完需要打包时,模块拆分会导致报错
因为项目将部分内容作为依赖进行导入,而Maven打包项目时在本地仓库找不到这些依赖就会报错
这时需要将所有模块进行install操作,安装到本地仓库,项目才能进行package操作
但如果每个模块都需要手动install就过于麻烦了,而聚合就解决了这个问题
介绍与实现
- **聚合:**将多个模块组织成一个整体,同时进行项目的构建。
- **聚合工程:**一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个】
- **作用:**快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)
在maven中,我们可以在聚合工程中通过 <moudules> 设置当前聚合工程所包含的子模块的名称。我们可以在 tlias-parent中,添加如下配置,来指定当前聚合工程,需要聚合的模块:
1
2
3
4
5
6
|
<!-- 聚合其他模块 -->
<modules>
<module>../tlias-pojo</module>
<module>../tlias-utils</module>
<module>../tlias-web-management</module>
</modules>
|
聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关
现在只要在聚合工程中进行打包即可
继承与聚合对比
- 作用
- 聚合用于快速构建项目
- 继承用于简化依赖配置、统一管理依赖
- 相同点:
- 聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点:
- 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
私服
私服简介
前面在讲解多模块开发的时候,所拆分的模块是可以在同一个公司各个项目组之间进行资源共享的
这个模块的资源共享,就需要通过接下来的 Maven 的私服来实现
本文不讲如何搭建私服,仅简单介绍如何连接上已有私服
连接步骤
1.设置私服的访问用户名/密码(在自己maven安装目录下的conf/settings.xml中的servers中配置)
1
2
3
4
5
6
7
8
9
10
11
|
<server>
<id>maven-releases</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>maven-snapshots</id>
<username>admin</username>
<password>admin</password>
</server>
|
2.设置私服依赖下载的仓库组地址(在自己maven安装目录下的conf/settings.xml中的mirrors中配置)
1
2
3
4
5
|
<mirror>
<id>maven-public</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
|
3.设置私服依赖下载的仓库组地址(在自己maven安装目录下的conf/settings.xml中的profiles中配置)
若是不加则只允许我们使用release仓库中的依赖,不允许使用snapshot仓库中的依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<profile>
<id>allow-snapshots</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>maven-public</id>
<url>http://localhost:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
|
4.IDEA的maven工程的pom.xml文件中配置上传(发布)地址(直接在tlias-parent中配置发布地址)
1
2
3
4
5
6
7
8
9
10
11
12
|
<distributionManagement>
<!-- release版本的发布地址 -->
<repository>
<id>maven-releases</id>
<url>http://localhost:8081/repository/maven-releases/</url>
</repository>
<!-- snapshot版本的发布地址 -->
<snapshotRepository>
<id>maven-snapshots</id>
<url>http://localhost:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
|
配置完成之后,就可以在tlias-parent中执行deploy生命周期,将项目发布到私服仓库中
idea会自动根据项目pom.xml中设置的版本<version>进行上传,如果后缀有SNAPSHOT则会自动上传到snapshot仓库,
若没有则会默认上传到releases仓库
在真实的企业开发中,私服都是在远程服务器中的,并不是在本地的。这里只是为了方便演示