Maven讲解之 依赖管理

本章节我们将通过两个例子来实例讲解一下Maven的依赖关系。

两个例子

新建两个Maven Project(War)。一客户模块和市场模块作为例子(只举业务逻辑例子,无核心代码)。另外Customer Model 将依赖于Market Model。

  • Market Model
  • 目录结构



maven中怎么通过pom文件解决子模块循环依赖_idea查看maven依赖关系


  • 操作点
  • install(install 该项目,使Maven 初次下载其生命周期管理的组件)

右键项目->Run as ->Maven install

  • compile(编译该项目形成Market的SNAPSHOT jar(编译后的class文件))

右键项目->Run as ->Maven build….. ->goals:compile

  • pom.xml

  1. 4.0.0
  2. com.sspts.oscar
  3. Market
  4. 0.0.1-SNAPSHOT
  5. war

Customer Model

目录结构


maven中怎么通过pom文件解决子模块循环依赖_maven provided_02


操作点

    • 统一管理jar包版本
    1. 
    2.  UTF-8
    3.  4.0.4.RELEASE
    4. 
    • 引用其他模块的jar包
    5. 
    6.  com.sspts.oscar
    7.  Market
    8.  0.0.1-SNAPSHOT
    9.  compiler
    10. 
    • 去掉对Spring core jar 包中对commons-logging的依赖
    11. 
    12. 
    13.  commons-logging
    14.  commons-logging
    15. 
    16. 
    • pom.xml
    17. 
    18.  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    19.  4.0.0
    20.  com.sspts.oscar
    21.  Customer
    22.  0.0.1-SNAPSHOT
    23.  war
    24. 
    25.  UTF-8
    26.  4.0.4.RELEASE
    27. 
    28. 
    29. 
    30. 
    31.  org.springframework
    32.  spring-aop
    33.  ${spring.version}
    34. 
    35. 
    36.  commons-logging
    37.  commons-logging
    38. 
    39. 
    40. 
    41. 
    42.  org.springframework
    43.  spring-aspects
    44.  ${spring.version}
    45. 
    46. 
    47.  org.springframework
    48.  spring-beans
    49.  ${spring.version}
    50. 
    51. 
    52.  org.springframework
    53.  spring-context
    54.  ${spring.version}
    55. 
    56. 
    57. 
    58.  com.sspts.oscar
    59.  Market
    60.  0.0.1-SNAPSHOT
    61.  compiler
    62. 
    63. 
    64. 
    65.  javax.servlet
    66.  javax.servlet-api
    67.  3.1.0
    68.  provided
    69. 
    70.

    注:本例子只引用了Spring 的部分jar包,请结合实际需求引用spring的jar包。

    实例讲解

    Maven 中最关键的部分,我们使用 Maven 最主要的就是使用它的依赖管理功能。要理解和掌握 Maven 的依赖管理,我们只需要解决一下几个问题:

    • 依赖的目的是什么

    当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,这是概念上的描述。那么如何在项目中以依赖的方式引入一个我们需要的 jar 包呢?

    答案非常简单,就是使用 dependency 标签指定被依赖 jar 包的坐标就可以了。如本章例子,Customer Model 引用到了Market Model 的SNAPSHOT


    1. com.sspts.oscar
    2. Market
    3. 0.0.1-SNAPSHOT
    4. compiler

    • 依赖的范围

    大家注意到上面的依赖信息中除了目标 jar 包的坐标还有一个 scope 设置,这是依赖的范围。依赖的范围有几个可选值,我们用得到的是:compile、test、provided 三个。

    • [1]从项目结构角度理解 compile 和 test 的区别


    maven中怎么通过pom文件解决子模块循环依赖_jar_03


    从上面的依赖关系可以看出不论是主程序(main下面的JAVA文件)还是测试程序(test下面的JAVA文件)都使用到了compile依赖,而test依赖只用于测试程序。

    • [2]从开发和运行这两个不同阶段理解 compile 和 provided 的区别


    maven中怎么通过pom文件解决子模块循环依赖_spring_04


    正如我们在Customer Model pom.xml中对 Servlet API的依赖范围定义所示,将Servlet API的依赖范围定义为provided,即在开发阶段我们会依赖Servlt API,一旦项目部署以后,项目将直接忽略Servlet API,二运行阶段酱油Servlet容器提供Servlet API。

    • [3]有效性总结


    maven中怎么通过pom文件解决子模块循环依赖_jar_05


    • 依赖的传递性

    A 依赖 B,B 依赖 C,A 能否使用 C 呢?那要看 B 依赖 C 的范围是不是 compile,如果是则可用,否则不可用。


    maven中怎么通过pom文件解决子模块循环依赖_idea查看maven依赖关系_06


    • 依赖的排除

    如果我们在当前工程中引入了一个依赖是 A,而 A 又依赖了 B,那么 Maven 会自动将 A 依赖的 B 引入当前工程,但是个别情况下 B 有可能是一个不稳定版,或对当前工程有不良影响。这时我们可以在引入 A 的时候将 B 排除。

    • 情景举例

    不排除依赖时


    maven中怎么通过pom文件解决子模块循环依赖_jar_07



    1. org.springframework
    2. spring-aop
    3. ${spring.version}


    • 排除依赖时


    maven中怎么通过pom文件解决子模块循环依赖_maven provided_08


      1. 
      2.  org.springframework
      3.  spring-aop
      4.  ${spring.version}
      5. 
      6. 
      7.  commons-logging
      8.  commons-logging
      9. 
      10. 
      11. 
      • 统一管理所依赖 jar 包的版本 
      对同一个框架的一组 jar 包最好使用相同的版本。为了方便升级框架,可以将 jar 包的版本信息统一提取出来。例如在Customer Model中我们在pom.xml对spring 以及sourceEncoding做了版本和格式的限制。
      • 统一声明版本号
      1. 
      2.  UTF-8
      3.  4.0.4.RELEASE
      4. 
      • 引用前面声明的版本号
      5. 
      6.  org.springframework
      7.  spring-aspects
      8.  ${spring.version}
      9. 
      • 依赖的原则:解决 jar 包冲突

      路径最短者优先


      maven中怎么通过pom文件解决子模块循环依赖_idea查看maven依赖关系_09


      路径相同时先声明者优先


      maven中怎么通过pom文件解决子模块循环依赖_spring_10


      这里“声明”的先后顺序指的是 dependency 标签配置的先后顺序。