maven中依赖、继承、聚合、dependencyManagement、parent标签、modules标签的作用

简介

Maven是Apache软件基金会组织维护的一款自动化构建工具,专注服务于Java平台的项目构建和依赖管理。Maven这个单词的本意是:专家,内行。读音是['meɪv(ə)n]或['mevn]。

依赖

依赖范围

maven中依赖常见的范围有 compile、provided、test 三种。

compile范围依赖:

  • 对主程序是否有效:有效
  • 对测试程序是否有效:有效
  • 是否参与打包:参与
  • 是否参与部署:参与
  • 典型例子:spring-core

provided范围依赖:

  • 对主程序是否有效:有效
  • 对测试程序是否有效:有效
  • 是否参与打包:不参与
  • 是否参与部署:不参与
  • 典型例子:server-api.jar

test范围依赖:

  • 对主程序是否有效:无效
  • 对测试程序是否有效:有效
  • 是否参与打包:不参与
  • 是否参与部署:不参与
  • 典型例子:junit

provided主要是针对web工程的。以前web开发,总是缺少server-api.jar,所以我们常去Tomcat的lib目录下拷过来使用。但是部署的时候会忽略,因为容器会提供,所以不会打包上去。故将 server-api.jar 设置为provided范围。

依赖传递&排除

当A工程依赖B工程,那么我们在给B工程导入其他依赖的话,A工程也会自动导入相同的依赖,这样依赖只用在pom.xml文件中导入一次,就比较方便。这就是依赖的传递性。
当然依赖的传递也不是绝对的,有些依赖就传递不过来。非compile范围的依赖不能传递。 这样我们也可以看出,provided和test范围就是给当前工程自己用的。所以在各个工程模块中,如果有需要就得重复声明依赖。

-----------------------------------------------------------华丽的分割线-----------------------------------------------------------

现在假设有这么个场景,B工程导入的依赖有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。想要排除某个依赖,就在依赖的gav坐标中,使用 exclusions 标签,里面可以定义多个 exclusion

比如在当前的mavenpro_b工程中,依赖了 mavenpro_c,mavenpro_c 又依赖了lombock。但是我mavenpro_b工程不想要lombok依赖,就可以使用哦 exclusions 标签进行排除。

排除前:

在这里插入图片描述
排除后:
在这里插入图片描述

依赖冲突的原则

之前说过,依赖存在传递性,当A依赖于B,而B又依赖于C,则A也会引入C的compile范围的依赖。
假设现在有这么一个场景,有三个工程,分别名为 mavenpro_a,mavenpro_b,mavenpro_c。
在这里插入图片描述
如上图所示,此时就发生依赖冲突了。mavenpro_a是依赖lombok 1.18.20还是 lombok 1.16.18呢?

一般来说选择版本较高的,因为版本较高的都会向下兼容。但是maven有自己的解决依赖版本问题的原则,就是就进优先,也就是路径最短者优先。那么怎么去看这个路径呢?
mavenpro_a到mavenpro_b再到lombok 1.16.18的路径短于 mavenpro_a到mavenpro_b到mavenpro_c再到lombok 1.18.20。故mavenpro_a最终会选择 lombok 1.16.18的依赖版本。
在这里插入图片描述
那么如果我就是想用 1.18.20 的版本的依赖呢?那就在该工程pom.xml中显示的声明即可。

-----------------------------------------------------------华丽的分割线-----------------------------------------------------------

现在换一个场景,假设还是三个工程 mavenpro_a,mavenpro_b,mavenpro_c。
mavenpro_a 依赖了 mavenpro_b和mavenpro_c,而在mavenpro_b和mavenpro_c都有lombok依赖,那么mavenpro_a 用谁的依赖呢?

此时从 mavenpro_a到lombok 1.16.18的路径和mavenpro_b到lombok 1.18.20的路径相等,该如何是好?
在这里插入图片描述
maven中规定,路径相同的时候,对依赖的取舍标准就叫做先声明者优先。 先声明指的是dependency标签的声明顺序。
在这里插入图片描述
在这里插入图片描述

依赖的统一管理

在最早学Spring的时候,导入依赖,我们都是根据Spring的模块按需导入。如:
在这里插入图片描述

当我们使用框架时,使用框架的一组jar包,最好都是版本一致的,毕竟不同版本之间总会有些改动。那么如果我想将所有的jar包版本都升级到 5.3.6 怎么办呢?最笨的办法就是手动去挨个修改,这样有多少个jar包就要修改多少次,这样并不可取。

推荐的方法就是,在 properties 标签内来自定义标签来统一版本号。这样我们只要修改了自定义标签内的值,那么其他地方凡是引用到了该自定义标签的值都会跟着修改。
在这里插入图片描述
properties标签配合自定义标签声明数据的配置并不是只能用于版本号管理,但是用的最多的是版本号管理。凡是需要统一声明后再引用的场合都可以使用。

继承

parent标签

假设现在有四个工程 mavenpro_a,mavenpro_b,mavenpro_c,mavenpro_d。mavenpro_a 、mavenpro_b 、mavenpro_c 都依赖mavenpro_d,此时如果mavenpro_d的版本发生变动,其他三个工程想要升级依赖版本,也要各自去修改,十分麻烦。
在这里插入图片描述
之前在单个工程中可以通过properties标签和自定义标签来统一依赖版本。那么多个工程之间如何统一呢? 就需要定义一个父工程来进行统一管理。

定义一个父工程 mavenpro_parent。在父工程中引入mavenpro_d 的依赖。

<?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>

    <groupId>org.example</groupId>
    <artifactId>mavenpro_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging> <!-- 父工程打包类型一定是 pom -->
    <properties>
        <mavenpro_d.version>3.0-SNAPSHOT</mavenpro_d.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>mavenpro_d</artifactId>
            <version>${mavenpro_d.version}</version>
        </dependency>
    </dependencies>
</project>

我们只需继承父工程,就能得到父工程中的compile范围的依赖。这样如果版本发生变动,我们只需要在父工程中修改即可,不需要变动子工程。
在这里插入图片描述

注意,父工程的打包类型一定要定义成 pom 类型 否则会报如下错误:
在这里插入图片描述

dependencyManagement

之前说过,我们在可以在工程中使用parent标签,这样就能获取到父工程中所有的依赖。假设现在有这么一个场景,还是四个工程 mavenpro_a,mavenpro_b,mavenpro_c,mavenpro_d以及一个mavenpro_parent父工程。此时mavenpro_a,mavenpro_b两个工程完全依赖父工程,而mavenpro_c只只需要父工程的部分依赖。那么该怎么办呢? 就是使用 dependencyManagement标签,可以按需导入。
此时父工程中有两个依赖

<?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>
    <groupId>org.example</groupId>
    <artifactId>mavenpro_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <mavenpro_d.version>3.0-SNAPSHOT</mavenpro_d.version>
        <spring.aop.version>5.3.6</spring.aop.version>
    </properties>
    <dependencyManagement>
        <dependencies>
        
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>mavenpro_d</artifactId>
                <version>${mavenpro_d.version}</version>
            </dependency>
            
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.aop.version}</version>
            </dependency>
            
        </dependencies>
    </dependencyManagement>
</project>

此时我们再去看 mavenpro_c ,即使使用了parent标签,但是依赖全无。因为,parent标签中的依赖,maven会帮我们自动下载,而dependencyManagement标签中的依赖,maven不会帮我们下载,需要我们自己按需引入!
在这里插入图片描述
于是我按需导入 aop 依赖

<?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>
    <groupId>org.example</groupId>
    <artifactId>mavenpro_c</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <artifactId>mavenpro_parent</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../mavenpro_parent/pom.xml</relativePath> <!-- 父工程 pom.xml 的相对路径-->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
    </dependencies>
</project>

可以看到,在导入aop依赖的时候,我并没有写版本号,这也是 dependencyManagement 标签带来的好处,我们在父工程中定义的依赖,子类在引入依赖时,可以不定义版本号,那么就默认的使用父工程的版本号。这称为maven的版本仲裁机制。

聚合

一个工程中的类想要被其它工程使用,那么我们需要将该工程打包成jar包的方式,被其它工程引用,即可使用。在maven使用 maven install 即可打包但装到我们的maven仓库中。

当工程渐渐变多,一个一个的maven install就变得繁琐起来,于是我们可以在父工程中通过 modules标签引入子工程,这样我们 maven install 父工程,则 modules 标签中的子工程也会被一键安装。

<?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>

    <groupId>org.example</groupId>
    <artifactId>mavenpro_parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>../mavenpro_a</module> <!-- 工程的相对位置 -->
        <module>../mavenpro_b</module>
    </modules>

    <properties>
        <mavenpro_d.version>3.0-SNAPSHOT</mavenpro_d.version>
        <spring.aop.version>5.3.6</spring.aop.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>mavenpro_d</artifactId>
                <version>${mavenpro_d.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring.aop.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值