Maven基础

核心思想:约定大于配置
其实约定大于配置这一思想在开发中经常出现
当程序中的某一个或者某一些参数没有配置的时候,程序会自动设定一个默认值。
这个默认值的设定,就称之为约定。
意义在于:减少不必要的配置。

Maven的仓库分为三种:

标准目录

目录 作用 $ 项目根目录,存放pom.xml和所有子目录 ${basedir}/src/main/java 存放 java 源代码 ${basedir}/src/main/resources 存放资源文件,如 propert 文件 ${basedir}/src/test/java 存放测试代码 ${basedir}/src/test/resources 存放测试的资源文件 ${basedir}/src/main/webapp/WEB-INF web 应用文件目录,如 web.xml,本地图片,jsp ${basedir}/target 打包输出目录 ${basedir}/target/classes 编译输出目录 ${basedir}/target/test-classes 测试编译输出目录

  • groupId:当前Maven构件隶属组织名(必须)
  • artifactId:项目的唯一标识符,项目的名称(必须)
  • version:当前版本(必须)
  • scope:依赖范围指定
  • packaging:打包方式
  • classifier:通常用于区分以上项目都相同的构件的不同版本

依赖范围是三种可见性的组合
有三种可见性,编译,测试,运行

  • compile:默认的依赖范围,对于编译,测试,运行三种都生效
  • test:仅对于测试生效,典型的就是 Junit
  • provided:对于编译,测试生效。比如 servlet-api.jar 在 Tomcat 中已经提供了,只需要编译与测试阶段提供即可。
  • runtime:对于测试,运行生效。如JDBC驱动实现。
    注:由于现在的开发多使用mybatis,所以JDBC的部分不需要在编译阶段处理。
  • system:与上述均不相同。使用 system 后必须通过 systemPath 元素指定依赖文件的路径,不依赖 Maven 仓库的解析,所以存在依赖关系不可移植的风险。

依赖冲突

众所周知,对于 Maven 而言,同一个groupId,artifactId下,只能使用一个 version


        org.mybatis
        mybatis
        3.3.0

        org.mybatis
        mybatis
        3.5.0

对于上述配置,将使用3.5.0的mybatis,可以理解为后配置覆盖前配置(覆盖策略)

※思考问题

现在,我们可以思考下,比如工程中需要引入A、B,而 A 依赖 1.0 版本的 C,B 依赖 2.0 版本的 C,那么问题来了,C 使用的版本将由引入A、B的顺序而定? 这显然不靠谱!如果 A 的依赖写在 B 的依赖后面,将意味着最后引入的是 1.0 版本的 C,很可能在运行阶段出现类(ClassNotFoundException)、方法(NoSuchMethodError)找不到的错误(因为B使用的是高版本的C)!

Maven 引入的传递性依赖机制,能大大简化依赖管理。大部分情况只需要关心项目的直接依赖,而不用关心依赖的依赖。但是当多个直接依赖的依赖出现冲突时,问题就令人抓狂了起来。

依赖传递有两种情况:

Maven有一定的智能,可以对 部分依赖进行调整来保证构件的唯一性。

因为只针对部分依赖,所以还是有误判的情况。因此,通过手动配置来优化依赖还是有必要的。
我们可以使用 maven-dependency-plugin 提供的三个目标来实现依赖分析

$ mvn dependency:list
$ mvn dependency:tree
$ mvn dependency:analyze

若需要更精细的分析,可以在命令后添加如下参数

-Dverbose
-Dincludes=:

软件开发依赖冲突问题,有四种原则:

  • 路径最短优先原则
  • 声明顺序优先原则
  • 排除原则
  • 版本锁定原则

Maven依赖调解遵循以下两大原则: 路径最短优先声明顺序优先

若依赖链的长度不同是,优先使用短的

a --> b --> x(1.1)      // dist(a->x) = 2
a --> c --> d --> x(1.2)    // dist(a->x) = 3

上述情况,优先使用版本x(1.1)的依赖

若依赖链的长度相同时,使用优先声明的

a --> b --> x(1.1)  // dist(a->x) = 2
a --> c --> x(1.2)  // dist(a->x) = 2

当 a 的 pom.xml 中优先声明 b,使用 x(1.1) 的依赖

简单暴力,在对应pom.xml中加入一下内容即可


  org.glassfish.jersey.containers
  jersey-container-grizzly2-http

      org.glassfish.hk2.external
      jakarta.inject

    ...

Original: https://www.cnblogs.com/buzuweiqi/p/16491270.html
Author: buzuweiqi
Title: Maven基础

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/584804/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球