Maven 高级: 继承与聚合

Maven 是一款构建和管理 Java 项目的工具。但是在实际开发中, 仅凭 Maven 的基础知识就比较难以应对了。 Maven 还提供了一些高级的功能,这些功能在构建和管理 Java 项目的时候用的也是非常多的。

Maven 高级内容包括:

  • 分模块设计与开发
  • 继承与聚合
  • 私服

在这里插入图片描述


在案例项目分模块开发之后啊,会看到 tlias-pojo、tlias-utils、tlias-web-management 中都引入了一个依赖 lombok 的依赖。在三个模块中分别配置了一次。

在这里插入图片描述

如果是做一个大型的项目,这三个模块当中重复的依赖可能会很多很多。如果每一个 Maven 模块里面,都来单独的配置一次,功能虽然能实现,但是配置是比较 繁琐 的。

可以用继承用来解决这问题的。


1. 继承

可以再创建一个父工程 tlias-parent ,然后让上述的三个模块 tlias-pojo、tlias-utils、tlias-web-management 都来继承这个父工程 。

然后再将各个模块中都共有的依赖,都 提取到 父工程 tlias-parent 中进行配置,只要子工程继承了父工程,依赖它也会继承下来,这样就无需在各个子工程中进行配置了。

在这里插入图片描述

  • 概念:继承描述的是两个工程间的关系,与java中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承。

  • 作用:简化依赖配置、统一管理依赖

  • 实现

    <parent>
        <groupId>...</groupId>
        <artifactId>...</artifactId>
        <version>...</version>
        <relativePath>....</relativePath>
    </parent>
    

了解了什么是继承以及继承的作用,以及在 maven 当中如何来实现这层继承关系。接下来就来创建这样一个 parent 父工程,就可以将各个子工程当中共有的这部分依赖统一的定义在父工程parent 当中,从而来简化子工程的依赖配置。

1.1 继承关系

我们当前的项目 tlias-web-management,还稍微有一点特殊,因为是一个 springboot 项目,而所有的 springboot 项目都有一个统一的父工程,就是 spring-boot-starter-parent。 与 java 语言类似,Maven 不支持多继承,一个 maven 项目只能继承一个父工程,如果继承了spring-boot-starter-parent,就没法继承我们自己定义的父工程 tlias-parent了。

那我们怎么来解决这个问题呢?

那此时,Java虽 然不支持多继承,但是可以支持多重继承,比如:A 继承 B, B 继承C。 那在Maven 中也是支持多重继承的,所以呢,就可以让自己创建的三个模块,都继承 tlias-parent,而tlias-parent 再继承 spring-boot-starter-parent,就可以了。 具体结构如下:

在这里插入图片描述


1.2 版本锁定

1.2.1 场景

如果项目中各个模块中都公共的这部分依赖,可以直接定义在父工程中,从而简化子工程的配置。

然而在项目开发中,还有一部分依赖,并不是各个模块都共有的,可能只是其中的一小部分模块中使用到了这个依赖。

比如:在 tlias-web-management、tlias-web-system、tlias-web-report 这三个子工程中,都使用到了 jwt 的依赖。 但是 tlias-pojo、tlias-utils 中并不需要这个依赖,那此时,这个依赖,不会直接配置在父工程 tlias-parent中,而是哪个模块需要,就在哪个模块中配置。

而由于是一个项目中的多个模块,那多个模块中,我们要使用的同一个依赖的版本要一致,这样便于项目依赖的统一管理。比如:这个 jwt 依赖,我们都使用的是 0.9.1 这个版本。

那假如说,项目要升级,要使用到 jwt 最新版本 0.9.2 中的一个新功能,那此时需要将依赖的版本升级到 0.9.2,那此时该怎么做呢 ?

第一步:去找当前项目中所有的模块的 pom.xml 配置文件,看哪些模块用到了 jwt 的依赖。

第二步:找到这个依赖之后,将其版本 version,更换为 0.9.2。

问题:如果项目拆分的模块比较多,每一次更换版本,我们都得找到这个项目中的每一个模块,一个一个的更改。 很容易就会出现,遗漏掉一个模块,忘记更换版本的情况。

那我们又该如何来解决这个问题,如何来统一管理各个依赖的版本呢?

答案:Maven 的版本锁定功能。

1.2.2 用法

在 maven 中,可以在父工程的 pom 文件中通过 <dependencyManagement> 来统一管理依赖版本。

父工程:

<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程:

<dependencies>
    <!--JWT令牌-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

注意:

  • 在父工程中所配置的 <dependencyManagement> 只能统一管理依赖版本,并不会将这个依赖直接引入进来。 这点和 <dependencies> 是不同的。

  • 子工程要使用这个依赖,还是需要引入的,只是此时就无需指定 <version> 版本号了,父工程统一管理。变更依赖版本,只需在父工程中统一变更。

1.2.3 属性配置

也可以通过自定义属性及属性引用的形式,在父工程中将依赖的版本号进行集中管理维护。 具体语法为:

1). 自定义属性

<properties>
	<lombok.version>1.18.24</lombok.version>
</properties>

2). 引用属性

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

接下来,就可以在父工程中,将所有的版本号,都集中管理维护起来。

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>

    <lombok.version>1.18.24</lombok.version>
    <jjwt.version>0.9.1</jjwt.version>
    <aliyun.oss.version>3.15.1</aliyun.oss.version>
    <jaxb.version>2.3.1</jaxb.version>
    <activation.version>1.1.1</activation.version>
    <jaxb.runtime.version>2.3.3</jaxb.runtime.version>
</properties>


<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>
</dependencies>

<!--统一管理依赖版本-->
<dependencyManagement>
    <dependencies>
        <!--JWT令牌-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>

        <!--阿里云OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>${aliyun.oss.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>${jaxb.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>${activation.version}</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>${jaxb.runtime.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

版本集中管理之后,我们要想修改依赖的版本,就只需要在父工程中自定义属性的位置,修改对应的属性值即可。

面试题:<dependencyManagement><dependencies> 的区别是什么?

  • <dependencies> 是直接依赖,在父工程配置了依赖,子工程会直接继承下来。
  • <dependencyManagement> 是统一管理依赖版本,不会直接依赖,还需要在子工程中引入所需依赖(无需指定版本)

2. 聚合

分模块设计与开发之后啊,项目被拆分为多个模块,而模块之间的关系,可能错综复杂。 那就比如当前的案例项目,结构如下(相对还是比较简单的):

在这里插入图片描述

此时,tlias-web-management 模块的父工程是 tlias-parent,该模块又依赖了 tlias-pojo、tlias-utils模块。 那此时,我们要想将 tlias-web-management 模块打包,是比较繁琐的。因为在进行项目打包时,maven会从本地仓库中来查找 tlias-parent父工程,以及它所依赖的模块 tlias-pojo、tlias-utils,而本地仓库目前是没有这几个依赖的。

所以,在打包 tlias-web-management 模块前,需要将 tlias-parent、tlias-pojo、tlias-utils 分别执行 install 生命周期安装到 maven 的本地仓库,然后再针对于 tlias-web-management 模块执行 package 进行打包操作。

那此时,试想一下,如果开发一个大型项目,拆分的模块很多,模块之间的依赖关系错综复杂,那此时要进行项目的打包、安装操作,是非常繁琐的。 而接下来,要讲解的 maven 的聚合就是来解决这个问题的,通过maven的聚合就可以轻松实现项目的一键构建(清理、编译、测试、打包、安装等)。

介绍

在这里插入图片描述

  • 聚合: 将多个模块组织成一个整体,同时进行项目的构建。
  • 聚合工程: 一个不具有业务功能的“空”工程(有且仅有一个pom文件) 【PS:一般来说,继承关系中的父工程与聚合关系中的聚合工程是同一个】
  • 作用: 快速构建项目(无需根据依赖关系手动构建,直接在聚合工程上构建即可)

实现

在 maven 中,我们可以在聚合工程中通过 <moudules> 设置当前聚合工程所包含的子模块的名称。我们可以在 tlias-parent 中,添加如下配置,来指定当前聚合工程,需要聚合的模块:

<!--聚合其他模块-->
<modules>
    <module>../tlias-pojo</module>
    <module>../tlias-utils</module>
    <module>../tlias-web-management</module>
</modules>

那此时,我们要进行编译、打包、安装操作,就无需在每一个模块上操作了。只需要在聚合工程上,统一进行操作就可以了。

测试: 执行在聚合工程 tlias-parent 中执行 package 打包指令

在这里插入图片描述

那 tlias-parent 中所聚合的其他模块全部都会执行 package 指令,这就是通过聚合实现项目的一键构建(一键清理clean、一键编译compile、一键测试test、一键打包package、一键安装install等)。


继承与聚合的对比

  • 作用

    • 聚合用于快速构建项目

    • 继承用于简化依赖配置、统一管理依赖

  • 相同点:

    • 聚合与继承的pom.xml文件打包方式均为pom,通常将两种关系制作到同一个pom文件中

    • 聚合与继承均属于设计型模块,并无实际的模块内容

  • 不同点:

    • 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些

    • 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值