栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 的依赖。



    4.0.0

    org.example
    mavenpro_parent
    1.0-SNAPSHOT
    pom 
    
        3.0-SNAPSHOT
    
    
        
            org.example
            mavenpro_d
            ${mavenpro_d.version}
        
    

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

注意,父工程的打包类型一定要定义成 pom 类型 否则会报如下错误:

dependencyManagement

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



    4.0.0
    org.example
    mavenpro_parent
    1.0-SNAPSHOT
    pom
    
        3.0-SNAPSHOT
        5.3.6
    
    
        
        
            
                org.example
                mavenpro_d
                ${mavenpro_d.version}
            
            
            
                org.springframework
                spring-aop
                ${spring.aop.version}
            
            
        
    

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

于是我按需导入 aop 依赖



    4.0.0
    org.example
    mavenpro_c
    1.0-SNAPSHOT
    
        mavenpro_parent
        org.example
        1.0-SNAPSHOT
        ../mavenpro_parent/pom.xml 
    
    
        
            org.springframework
            spring-aop
        
    

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

聚合

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

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



    4.0.0

    org.example
    mavenpro_parent
    1.0-SNAPSHOT
    pom

    
        ../mavenpro_a 
        ../mavenpro_b
    

    
        3.0-SNAPSHOT
        5.3.6
    
    
        
            
                org.example
                mavenpro_d
                ${mavenpro_d.version}
            
            
                org.springframework
                spring-aop
                ${spring.aop.version}
            
        
    

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459290.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号