Maven 的依賴沖突
1、什麽是依賴傳遞
添加一個 struts2-core 的依賴,結果會發現所有關於 struts2 的依賴都會添加進來。
項目依賴 struts2-core-2.3.24.jar ,而 struts2-core-2.3.24.jar 會依賴 xwork-core-2.3.24.jar 等等。
所以這些 jar包 也都出現在我們的 maven工程 當中,這種現象就叫做依賴傳遞。
同理,我們依賴 service層 ,相關的依賴包也依賴傳遞了過來。
2、依賴沖突
Ⅰ、依賴沖突的產生
我們添加下面兩個依賴:
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency>
我們發現這兩個 jar包 同時依賴了 spring-beans
struts2-spring-plugin 依賴 spring-beans-3.0.5,spring-context 依賴 spring-beans-4.2.4,但是發現 spring-beans-3.0.5 加入到工程中,而我們希望 spring-beans-4.2.4 加入到工程中,這就造成了依賴沖突。
Ⅱ、解決依賴沖突的方法
方法一:依賴調解原則
maven 自動按照下邊的原則調解:
①第一聲名者優先原則
在 pom 文件定義依賴,以先聲明的依賴為準。
例子:上面先依賴的 struts2-spring-plugin ,故加入到工程中的依賴為 spring-beans-3.0.5 。
②路徑近者優先原則
例如:A 依賴 spring-beans-4.2.4 ,A 依賴 B,B 依賴 spring-beans-3.0.5,則 spring-beans-4.2.4 優先被依賴在 A 中。這是因為 spring-beans-4.2.4 相對 spring-beans-3.0.5 被 A 依賴的路徑最近。
方法二:排除依賴
上邊的問題也可以通過依賴排除解決。
例如:在 struts2-spring-plugin 的依賴中設置添加排除依賴,排除 spring-beans-3.0.5。
<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.3.24</version> <!-- 排除 spring-beans 的依賴 --> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </exclusion> </exclusions> </dependency>
方法三:鎖定版本(企業開發中常用)
面對眾多的依賴,用 版本鎖定 可以不用考慮依賴路徑、聲明優化等因素,可以采用直接鎖定版本的方法缺點依賴構建的版本。
例如:下面鎖定了 spring-beans 和 spring-context 的版本:
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.ys</groupId> <artifactId>maven-project</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!-- 屬性 --> <properties> <spring.version>4.2.4.RELEASE</spring.version> <properties/> <!-- 鎖定版本:spring版本為 4.2.4 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencies> </project>
註意:
在工程中鎖定依賴的版本並不代表在工程中添加了依賴,如果需要添加鎖定版本的依賴,需要單獨添加依賴。
在添加的依賴中不再需要指定版本了,因為上面已經鎖定了版本。
Maven 的依賴沖突