maven在編譯、測試和運行的時候使用的是三套不一樣的classpath,pom中的依賴配置項的scope屬性就是用來配置該依賴項在哪一個範圍內生效。Maven有下邊幾種依賴範圍:java
compile:編譯依賴範圍。若是沒有依賴包沒有指定scope屬性,那麼默認狀況下就是此依賴範圍。這個依賴範圍對於編譯、測試和運行三種classpath都有效。好比說spring-beans這個依賴包。spring
test:測試依賴範圍。只對測試classpath有效。在編譯主代碼或者運行項目的時候是沒法使用此包的。好比說junit。sql
provided:已提供依賴範圍。對於編譯和測試的classpath有效,在運行無效。好比說servlet-api,在編譯和測試的時候須要這個依賴包,但在項目運行的時候不須要。由於tomcat已經提供了這個包。api
runtime:運行時依賴範圍。對於測試和運行的classpath有效,對於編譯無效。好比jdbc驅動包。由於代碼都是針對jdbc接口去寫的,沒有針對實現。因此在編譯時即便沒有驅動的實現包也是能夠編譯經過的。但若是要測試或者運行的時候,就要加載實現包了。tomcat
system:系統依賴範圍。該依賴與三種classpath的關係相似於provided。但必須與systemPath元素配合使用才能夠,但這種狀況雖然能夠指定系統的jar包路徑,但形成了與本機綁定的狀況,沒法移植maven
<dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-my</artifactId> <version>1</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency>
依賴範圍 | 編譯classpath有效 | 測試classpath有效 | 運行classpath有效 | 例子 |
---|---|---|---|---|
compile | Y | Y | Y | spring-beans |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驅動實現 |
system | Y | Y | - | 本地的,maven倉庫以外的類庫文件 |
假如項目A的依賴關係是A->B-C-X(1.0),A->D-X(2.0)。這個時候有兩個版本的X,那麼選哪個呢。maven依賴調解的第一個原則是路徑短者優先
。因此會引入X的2.0版本。ide
若是依賴路徑的長度相同的話,該怎麼處理呢?好比說A-B-Y(1.0),A-C-Y(2.0)。這個時候會應用第二個原則最早聲明者優先
。若是B的依賴聲明在C以前,那麼引入的Y的版本就是1.0.測試
好比說這樣的依賴關係A->B,B->X(可選),B->Y(可選)。假如A對B的依賴範圍是compile,B對X和Y的依賴範圍也是compile,那麼根據依賴的傳遞性,A也會引入X和Y。可是這裏X和Y對B來講是可選依賴,A就不會引入X和Y。A若是要使用X和Y須要單獨引入!spa
<optional>true</optional>
依賴的傳遞性能夠很方便的引入項目須要的依賴,但也存在一些問題。假如A->B,B->C。可是這裏的C是SNAPSHOT版本的,會影響項目的穩定性。因此在構建A項目的時候須要把這個快照版本排除掉,單獨的在A的pom文件中申明對C的可靠版本的依賴。code
<project> <groupId>com.clgate.cn</groupId> <artifactId>A</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>com.clgate.cn</groupId> <artifactId>B</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>com.clgate.cn</groupId> <artifactId>C</artifactId> </exclusions> </exclusions> </dependency> <dependency> <groupId>com.clgate.cn</groupId> <artifactId>C</artifactId> <version>1.1.1</version> </dependency> </dependencies> </project>
主要的目的就是統一相同groupId,不一樣artifactId的版本
<project> xxxxx xxxxx xxxxx <properties> <spring.version></spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project>