• Maven入门-4.Maven的依赖


    1、Maven的依赖

    Maven的依赖通过dependencis元素来配置依赖,这是Maven最强大的特性之一。它支持传递性依赖。

    1.1 添加依赖

    在Maven中需要使用在dependencies中定义一个或者多个dependency元素,来声明项目的一个或者多个依赖。
    每个依赖元素dependency包括:

    例如:为项目添加junit测试的jar包,可以按如下方式定义

    1. <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/maven-v4_0_0.xsd " >
    2. <modelVersion>4.0.0</modelVersion>
    3. <groupId>com.fz</groupId>
    4. <artifactId>ShiroTest</artifactId>
    5. <packaging>war</packaging>
    6. <version>0.0.1-SNAPSHOT</version>
    7. <name>ShiroTest Maven Webapp</name>
    8. <url> http://maven.apache.org </url>
    9. <dependencies>
    10. <dependency>
    11. <groupId>junit</groupId>
    12. <artifactId>junit</artifactId>
    13. <version>4.11</version>
    14. <!--不声明依赖范围scope,默认是compile-->
    15. <scope>test</scope>
    16. </dependency>
    17. </dependencies>
    18. </project>

    1.2 依赖范围(sope)

    1. <dependency>
    2. <!--
    3. compile(默认):编译范围的依赖,它在编译和打包的时候都会把该依赖打包进去
    4. test:测试依赖范围,它在编译和打包的时候都不会把该依赖打包进去
    5. provided:在编译和测试范围有效,最后生成war包时不会打包进去。
    6. runtime:运行时依赖,编译的时候不依赖。
    7. system:系统依赖范围
    8. import:导入依赖范围
    9. -->
    10. <scope></scope>
    11. </dependency>

    依赖范围与classpath的关系

    依赖范围Scope 对于编译classpath有效 对于测试classpath有效 对于运行时classpath有效 例子
    compile Y Y Y spring-core
    test Y JUnit
    provided Y Y servlet-api
    runtime Y Y JDBC驱动实现
    system Y Y 本地的,Maven仓库之外的类库文件

    1.3 依赖的传递性

    在Maven中一个依赖不仅仅是一个JAR。它是一个POM文件,这个POM可能也声明了对其它构件的依赖。这些依赖的依赖叫做传递性依赖
    所谓传递性依赖就是: 如果项目A依赖于项目B,项目B自身依赖于项目C,那么项目A它也依赖于项目C的依赖。
    这种依赖是基于compile这个范围进行依赖
    假如你的项目中需要依赖一个A库,这个A库自身又依赖了3个其它库。当你在dependencies中配置了A库的依赖的时候,则Maven会自动依赖3个其他库。不用你再自己去依赖了。就像Spring和Hibernate一样。你配置的时候,只需要配置Spring和Hibernate即可。
    Maven在下载相应依赖的jar的时候,还会下载该jar的pom文件。这个文件对于传递性依赖特别重要。
    这个pom文件跟我们现在编写的pom.xml文件没太大区别,打开后其实也是一样。
    如下是hibernate-core-4.3.10.Final.jar的pom文件(hibernate-core-4.3.10.Final.pom)

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    3. <modelVersion>4.0.0</modelVersion>
    4. <groupId>org.hibernate</groupId>
    5. <artifactId>hibernate-core</artifactId>
    6. <version>4.3.10.Final</version>
    7. <dependencies>
    8. <dependency>
    9. <groupId>org.jboss.logging</groupId>
    10. <artifactId>jboss-logging</artifactId>
    11. <version>3.1.3.GA</version>
    12. <scope>compile</scope>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.jboss.logging</groupId>
    16. <artifactId>jboss-logging-annotations</artifactId>
    17. <version>1.2.0.Beta1</version>
    18. <scope>compile</scope>
    19. </dependency>
    20. <dependency>
    21. <groupId>org.jboss.spec.javax.transaction</groupId>
    22. <artifactId>jboss-transaction-api_1.2_spec</artifactId>
    23. <version>1.0.0.Final</version>
    24. <scope>compile</scope>
    25. </dependency>
    26. <dependency>
    27. <groupId>dom4j</groupId>
    28. <artifactId>dom4j</artifactId>
    29. <version>1.6.1</version>
    30. <scope>compile</scope>
    31. </dependency>
    32. <!-----------省略部分----------->
    33. </dependencies>
    34. <name>Core Hibernate O/RM functionality</name>
    35. <description>The core O/RM functionality as provided by Hibernate</description>
    36. <url>http://hibernate.org</url>
    37. <organization>
    38. <name>Hibernate.org</name>
    39. <url>http://hibernate.org</url>
    40. </organization>
    41. <issueManagement>
    42. <system>jira</system>
    43. <url>https://hibernate.atlassian.net/browse/HHH</url>
    44. </issueManagement>
    45. <scm>
    46. <url>http://github.com/hibernate/hibernate-orm</url>
    47. <connection>scm:git:http://github.com/hibernate/hibernate-orm.git</connection>
    48. <developerConnection>scm:git:git@github.com:hibernate/hibernate-orm.git</developerConnection>
    49. </scm>
    50. <licenses>
    51. <license>
    52. <name>GNU Lesser General Public License</name>
    53. <url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
    54. <comments>See discussion at http://hibernate.org/license for more details.</comments>
    55. <distribution>repo</distribution>
    56. </license>
    57. </licenses>
    58. <developers>
    59. <developer>
    60. <id>hibernate-team</id>
    61. <name>The Hibernate Development Team</name>
    62. <organization>Hibernate.org</organization>
    63. <organizationUrl>http://hibernate.org</organizationUrl>
    64. </developer>
    65. </developers>
    66. </project>

    可以看到hibernate-core-4.3.10.Final.pom文件中已经定义了hibernate-core-4.3.10.jar自己所依赖的jar包了。

    1.2.1 依赖传递性的冲突问题

    1. 第一种情况


    项目A依赖于项目B1.0 ,项目C依赖于项目B1.1。项目D同时依赖于项目A和C,那么哪一个写在前面就先依赖哪个版本。
    也就是说到底依赖于log4j1.2.17还是log4j1.2.16,决定于它的dependency出现的先后顺序。
    哪个依赖的顺序在前面就依赖哪个
    可见上面user-core在user-log前面,而user-core的log4j是1.2.17。那么最终user-dao的log4j就是1.2.17版本
    同理,如果换个位置。user-log在user-core的前面。

    1. <dependencies>
    2. <dependency>
    3. <groupId>com.fz.user</groupId>
    4. <artifactId>user-log</artifactId>
    5. <version>0.0.1-SNAPSHOT</version>
    6. </dependency>
    7. <dependency>
    8. <groupId>com.fz.user</groupId>
    9. <artifactId>user-core</artifactId>
    10. <version>0.0.1-SNAPSHOT</version>
    11. </dependency>
    12. </dependencies>

    那么结果就是

    2. 第二种情况


    如果路径的长短不一致,就选择最小路径
    user-dao中的log4j路径:user-dao=====>user-core=====>log4j1.2.17
    user-log中的log4j路径:user-log=====>log4j1.2.16
    可见user-log的log4j路径要短一些,所以这里是1.2.16

    如果这里把user-log换成user-core的话,那么user-core的log4j路径也是比user-dao的路径短。结果肯定是log4j1.2.17

    假如我不想依赖user-core和user-log两个模块中的log4j呢?
    那就自己再添加一个dependency试试。

    可以看出Maven会优先依赖自己定义的那个dependeny

    1.2.2 通过exclusions元素排除不想要的传递性依赖

    以上的问题可以通过更改相应的顺序来确定依赖的版本,当然也可以使用依赖的排除功能。来精确的控制所使用的版本。
    排除依赖:就是将该模块中的**jar包给移除掉。
    例如:以下的情况肯定是使用了user-log的log4j版本,因为它的顺序在前面。假如现在不想通过调整顺序来改版本那就可以使用排除依赖。

    排除依赖是在dependency元素下的exclusions元素,例如:我们把user-log中的log4j排除掉,那就只能去user-core中找log4j了

    可以看出虽然user-log写在了上面,但是通过exclusion还是会把该模块中的log4j给排除掉。

    1.2.3 依赖传递性冲突问题解决办法总结

    1. 通过调整dependency的顺序来解决:哪个依赖的顺序在前面就依赖哪个
    2. 自己添加一个dependeny来解决:因为该路径是最小的。
    3. 通过exclusions元素排除不想要的传递性依赖

    1.4 依赖版本的界限

    在依赖某个项目的时候,你可以不必指定特定的某个版本。也可以指定一个版本范围
    (,) 不包含
    [,] 包含
    例如:依赖一个Junit的大于等于3.8 但是小于4.0 的版本

    1. <dependency>
    2. <groupId>junit</groupId>
    3. <artifactId>junit</artifactId>
    4. <version>[3.8,4.0)</version>
    5. </dependency>
  • 相关阅读:
    FFT加速多项式乘法C语言版(基2FFT)
    springboot2中@ConfigurationProperties装载yml文件的时候调取出现值为null的解决办法
    LeetCode27-移除元素
    dom4j在解析xml文件的时候将" "解析成空格的解决办法
    LeetCode17- 电话号码的字母组合
    LeetCode19- 删除链表的倒数第N个节点
    LeetCode14- 最长公共前缀
    LeetCode20- 有效的括号
    LeetCode21- 合并两个有序链表
    MySQL单表百万数据记录分页性能优化
  • 原文地址:https://www.cnblogs.com/meet/p/6417496.html
走看看 - 开发者的网上家园