Maven的依賴

一、Maven的依賴

Maven的依賴經過dependencis元素來配置依賴,這是Maven最強大的特性之一。它支持傳遞性依賴。html

1.1 添加依賴

在Maven中須要使用在dependencies中定義一個或者多個dependency元素,來聲明項目的一個或者多個依賴。 
每一個依賴元素dependency包括: 
 
例如:爲項目添加junit測試的jar包,能夠按以下方式定義java

<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 " >      <modelVersion>4.0.0</modelVersion>      <groupId>com.fz</groupId>      <artifactId>ShiroTest</artifactId>      <packaging>war</packaging>      <version>0.0.1-SNAPSHOT</version>      <name>ShiroTest Maven Webapp</name>      <url> http://maven.apache.org </url>      <dependencies>          <dependency>              <groupId>junit</groupId>              <artifactId>junit</artifactId>              <version>4.11</version>              <!--不聲明依賴範圍scope,默認是compile-->              <scope>test</scope>          </dependency>      </dependencies> </project>

1.2 依賴範圍(sope)

<dependency>    <!--     compile(默認):編譯範圍的依賴,它在編譯和打包的時候都會把該依賴打包進去    test:測試依賴範圍,它在編譯和打包的時候都不會把該依賴打包進去    provided:在編譯和測試範圍有效,最後生成war包時不會打包進去。    runtime:運行時依賴,編譯的時候不依賴。    system:系統依賴範圍    import:導入依賴範圍     -->    <scope></scope></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)git

<?xml version="1.0" encoding="UTF-8"?><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">  <modelVersion>4.0.0</modelVersion>  <groupId>org.hibernate</groupId>  <artifactId>hibernate-core</artifactId>  <version>4.3.10.Final</version>  <dependencies>    <dependency>      <groupId>org.jboss.logging</groupId>      <artifactId>jboss-logging</artifactId>      <version>3.1.3.GA</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>org.jboss.logging</groupId>      <artifactId>jboss-logging-annotations</artifactId>      <version>1.2.0.Beta1</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>org.jboss.spec.javax.transaction</groupId>      <artifactId>jboss-transaction-api_1.2_spec</artifactId>      <version>1.0.0.Final</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>dom4j</groupId>      <artifactId>dom4j</artifactId>      <version>1.6.1</version>      <scope>compile</scope>    </dependency>    <!-----------省略部分----------->  </dependencies>  <name>Core Hibernate O/RM functionality</name>  <description>The core O/RM functionality as provided by Hibernate</description>  <url>http://hibernate.org</url>  <organization>    <name>Hibernate.org</name>    <url>http://hibernate.org</url>  </organization>  <issueManagement>    <system>jira</system>    <url>https://hibernate.atlassian.net/browse/HHH</url>  </issueManagement>  <scm>    <url>http://github.com/hibernate/hibernate-orm</url>    <connection>scm:git:http://github.com/hibernate/hibernate-orm.git</connection>    <developerConnection>scm:git:git@github.com:hibernate/hibernate-orm.git</developerConnection>  </scm>  <licenses>    <license>      <name>GNU Lesser General Public License</name>      <url>http://www.gnu.org/licenses/lgpl-2.1.html</url>      <comments>See discussion at http://hibernate.org/license for more details.</comments>      <distribution>repo</distribution>    </license>  </licenses>  <developers>    <developer>      <id>hibernate-team</id>      <name>The Hibernate Development Team</name>      <organization>Hibernate.org</organization>      <organizationUrl>http://hibernate.org</organizationUrl>    </developer>  </developers></project>

能夠看到hibernate-core-4.3.10.Final.pom文件中已經定義了hibernate-core-4.3.10.jar本身所依賴的jar包了。github

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的前面。spring

<dependencies> <dependency>        <groupId>com.fz.user</groupId>        <artifactId>user-log</artifactId>        <version>0.0.1-SNAPSHOT</version>    </dependency>    <dependency>        <groupId>com.fz.user</groupId>        <artifactId>user-core</artifactId>        <version>0.0.1-SNAPSHOT</version>    </dependency></dependencies>

那麼結果就是 
apache

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 
api

假如我不想依賴user-core和user-log兩個模塊中的log4j呢? 
那就本身再添加一個dependency試試。 
 
能夠看出Maven會優先依賴本身定義的那個dependenyapp

1.2.2 經過exclusions元素排除不想要的傳遞性依賴

以上的問題能夠經過更改相應的順序來肯定依賴的版本,固然也能夠使用依賴的排除功能。來精確的控制所使用的版本。 
排除依賴:就是將該模塊中的**jar包給移除掉。 
例如:如下的狀況確定是使用了user-log的log4j版本,由於它的順序在前面。假如如今不想經過調整順序來改版本那就能夠使用排除依賴。 
 
排除依賴是在dependency元素下的exclusions元素,例如:咱們把user-log中的log4j排除掉,那就只能去user-core中找log4j了 
 
能夠看出雖然user-log寫在了上面,可是經過exclusion仍是會把該模塊中的log4j給排除掉。dom

1.2.3 依賴傳遞性衝突問題解決辦法總結

  1. 經過調整dependency的順序來解決:哪一個依賴的順序在前面就依賴哪一個maven

  2. 本身添加一個dependeny來解決:由於該路徑是最小的。

  3. 經過exclusions元素排除不想要的傳遞性依賴

1.4 依賴版本的界限

在依賴某個項目的時候,你能夠沒必要指定特定的某個版本。也能夠指定一個版本範圍 
(,) 不包含 
[,] 包含 
例如:依賴一個Junit的大於等於3.8 可是小於4.0 的版本

<dependency>    <groupId>junit</groupId>    <artifactId>junit</artifactId>    <version>[3.8,4.0)</version></dependency>
相關文章
相關標籤/搜索