Maven高级

介绍了Maven的分模块开发,继承与聚合以及如何连接私服

Maven高级

分模块设计与开发

顾名思义指的就是我们在设计一个 Java 项目的时候,将一个 Java 项目拆分成多个模块进行开发

如果不分模块开发,将所有业务代码全部写在一个Java项目当中,随着项目业务的扩张,项目的管理和维护将会愈发困难

所以在项目设计阶段,就可以将一个大的项目拆成若干个独立的模块

拆分策略

比如一个商城系统就可以拆成多个小模块

  1. 策略一:按照功能模块拆分,比如:公共组件、商品模块、搜索模块、购物车模块、订单模块等
  2. 策略二:按层拆分,比如:公共组件、实体类、控制层、业务层、数据访问层
  3. 策略三:按照功能模块 + 层拆分

image-20250926214245243

实现

此处按模块拆分进行演示

分模块开发需要先针对模块功能进行设计,再进行编码。不会先将工程开发完毕,然后进行拆分

此处以演示为主,故将项目开发后进行拆分

在项目同目录下创建一个模块用于存放项目的实体类(创建普通Java模块即可):

image-20250926220908113

将项目中的实体类存入其中:

image-20250926221342389

给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>
image-20250926221956188

在项目中导入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中进行配置,只要子工程继承了父工程,依赖它也会继承下来,这样就无需在各个子工程中进行配置了

image-20250927133716766

实现方式:

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:父工程或聚合工程,该模块不写代码,仅进行依赖管理

image-20250927134728474
 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中的重写)

在实际项目中,子工程一般会创建在父工程内,这样看起来更直观

image-20250927141412429
版本锁定

那么问题又来了,上述方法只解决了所有模块共有的依赖的版本控制,但有些依赖只有部分模块需要,其余模块不需要,这种情况就解决不了了

有人可能会觉得将所有依赖都放在父工程不就好了,但如果将所有的依赖全部放到了父工程,当别人只想使用某个子模块时,就会把所有的依赖全部继承过来,造成严重的性能与资源浪费

为了解决这种情况,可以在父工程的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>标签中设置自定义属性统一管理版本号

image-20250927145248932

聚合

当项目开发完需要打包时,模块拆分会导致报错

因为项目将部分内容作为依赖进行导入,而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>

聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关

现在只要在聚合工程中进行打包即可

image-20250927180657713
继承与聚合对比
  • 作用
    • 聚合用于快速构建项目
    • 继承用于简化依赖配置、统一管理依赖
  • 相同点:
    • 聚合与继承的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仓库

在真实的企业开发中,私服都是在远程服务器中的,并不是在本地的。这里只是为了方便演示

本站于2025年3月26日建立
使用 Hugo 构建
主题 StackJimmy 设计