美文网首页
(二)Maven之坐标和依赖

(二)Maven之坐标和依赖

作者: 简笔话_Golden | 来源:发表于2019-06-09 20:03 被阅读0次
    image.png

    目录
    [TOC]

    坐标

    引言: 坐标是依赖管理的基础,是构建的唯一标识。

    组成元素: 使用groupId、artifactId、version、packaging、classifier标签即可定义一组坐标
    规定:groupId,artifactId,version是必须定义的,
    packaging的定义是可选的,classifier是不能直接定义的,而是以后附加的插件帮助生成的。

    <groupId> org.sonatype.nexus </groupId>
    <artifactId> nexus-indexer </artifactId>
    <version> 2.0.0 </version>
    <packaging> jar </packaging>
    
    groupId: 定义了Maven项目隶属的<u>实际项目</u>。

    groupId命名误区:

    • Maven项目不一定和实际项目一一对应。实际项目可能被划分为多个Maven项目
    • 不应该定义到项目隶属的组织或公司级别,因为组织或公司可能有多个项目。
    • 与java包名命名方式相似,通常以域名反向对应。
    artifactId: 定义了下实际项目的一个<u>Maven项目</u>
    • 建议使用实际项目名作为artifactId的前缀。
    • 一般来说,项目中Java类的包都应该基于项目的groupId和artifactId.
    version: 定义了Maven项目当前所处的版本。
    packaging: 定义了Maven项目的打包方式。

    打包方式通常与所生成构件扩展名对应,但是不是绝对的,而且打包方式会影响构建的生命周期。

    classifier: 定义了构建输出的一些附属构件。如:在包中生成的文档或源代码。

    依赖

    eg:
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>1.1.0.Final</version>
                <scope>provided</version>
                <optional>true</optional>
                  <exclusions>
                    <exclusion>
                        <groupId>XXXX</groupId> 
                        <artifactId>XXX</artifactId>
                    </exclusion>
            </dependency>
    

    每个依赖包含的元素有:

    • groupId,artifactId,version: 依赖的基本坐标
    • type: 依赖的类型,对应定义坐标时的packaging,默认值为jar.
    • scope: 依赖的范围
    • optional: 当前依赖是否可选
    • exclusions: 用来排除传递性依赖
    依赖范围【scope】

    Maven有三种classpath,分别供编译时(编译项目主代码)、测试时(编译和执行测试代码)、运行时(项目实际运行时)使用。
    依赖范围: 用来控制依赖同三种classpath的关系,即:是否将依赖引入相应的classpath中。

    依赖范围(scope) 编译classpath 生效 测试classpath 生效 运行时classpath生效 栗子
    compile Y Y Y spring-core
    test N Y N JUit
    provided Y Y Y N servlet-api
    runtime N Y Y JDBC驱动实现
    sytem Y Y N 除本地的Maven仓库外的jar包
    • 依赖范围不仅可以控制依赖和classpath的关系,还对传递性依赖产生影响
    • 可选依赖不能被传递!!!

    扩展: 为什么要使用可选依赖属性(optional)呢?
    eg: 项目B进入了X、Y的两个可选依赖,一般由业务形态决定的,业务上存在互斥性,用户不可能同时使用X、Y的功能。
    理想情况,其实是不应该使用可选依赖的,本着“单一职责”设计原则,最好分离开来设计。

    传递性依赖
    compile test provided runtime
    compile compile 不传递 不传递 runtime
    test test 不传递 不传递 test
    provided provied 不传递 provied provided
    runtime runtime 不传递 不传递 runtime

    注: 左边第一列是第一直接依赖,最上边一行是第二直接依赖。

    依赖调解

    当产生重复依赖冲突时,采用以下原则解决:

    • 第一原则: 依赖路径最近者优先
      eg: 路径1: A -> B -> C -> X(version:1.0)
      路径2: A -> D -> X(version:2.0)
      因此原则,传递性依赖X(version:2.0)将会被项目引用。

    • 第二原则: 路径长度相同,将由pom.xml总依赖声明的顺序决定。
      eg: 路径1: A -> B -> Y(version:1.0)
      路径2: A -> C -> Y(version:2.0)
      若C的引入顺序在B的前面,则 传递性依赖Y(version:2.0)将会被项目引用。

    最佳实践
    • 排除依赖: 使用exclusion标签定义。
    • 归类依赖: 运用Maven属性,使用properties元素定义Maven属性,并引用即可。
    • 优化依赖:

    mvn dependency:list (以列表方式展示项目依赖列表,包含传递性依赖)
    mvn dependency:tree (以树形结构展示项目依赖列表)

    相关文章

      网友评论

          本文标题:(二)Maven之坐标和依赖

          本文链接:https://www.haomeiwen.com/subject/fianxctx.html