以下面dependency為例
1 <dependency> 2 <groupId>javax.servlet</groupId> 3 <artifactId>javax.servlet-api</artifactId> 4 <version>3.1.0</version> 5 <scope>provided</scope> 6 </dependency>
當子工程中引入某個依賴時,可見其設置<scope>provided</scope>,那么后續依賴該工程的所有項目會可能出現找不到這個依賴,原因是:
1.provided是沒有傳遞性的。即,如果你依賴的某個jar包,它的某個jar的范圍是provided,那么該jar不會在你的工程中依靠jar依賴傳遞加入到你的工程中。
2.provided具有繼承性,上面的情況,如果需要統一配置一個組織的通用的provided依賴,可以使用parent,然后在所有工程中繼承
比如:我現在有個工程結構圖如下:
假設GranParent中的pom.xml是個超級pom.xml文件,
Parent繼承GranParent
1 <modelVersion>4.0.0</modelVersion> 2 <groupId>com.alice</groupId> 3 <artifactId>Parent</artifactId> 4 <version>1.0.0-SNAPSHOT</version> 5 6 <parent> 7 <groupId>com.alice</groupId> 8 <artifactId>GrandParent</artifactId> 9 <version>1.0.0</version> 10 </parent> 11 12 <modules> 13 <module>childA</module> 14 <module>childB</module> 15 <module>childB</module> 16 </modules> 17 <packaging>pom</packaging>
childA的pom.xml
1 <parent> 2 <groupId>com.alice</groupId> 3 <artifactId>Parent</artifactId> 4 <version>1.0.0-SNAPSHOT</version> 5 </parent> 6 <artifactId>childA</artifactId> 7 8 <name>childA</name> 9 <packaging>jar</packaging> 10 11 <dependencies> 12 <dependency> 13 <groupId>javax.servlet</groupId> 14 <artifactId>javax.servlet-api</artifactId> 15 <version>3.1.0</version> 16 <scope>provided</scope> 17 </dependency> 18 <dependencies>
childB的pom.xml,其中依賴childA
1 <modelVersion>4.0.0</modelVersion> 2 <parent> 3 <groupId>com.alice</groupId> 4 <artifactId>Parent</artifactId> 5 <version>1.0.0-SNAPSHOT</version> 6 </parent> 7 <artifactId>childB</artifactId> 8 9 <name>childB</name> 10 <packaging>jar</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>com.alice</groupId> 15 <artifactId>childA</artifactId> 16 <version>1.0.0-SNAPSHOT</version> 17 </dependency> 18 </dependencies>
childC的pom.xml,其中依賴childB
1 <modelVersion>4.0.0</modelVersion> 2 <parent> 3 <groupId>com.alice</groupId> 4 <artifactId>Parent</artifactId> 5 <version>1.0.0-SNAPSHOT</version> 6 </parent> 7 <artifactId>childC</artifactId> 8 9 <name>childC</name> 10 <packaging>jar</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>com.alice</groupId> 15 <artifactId>childB</artifactId> 16 <version>1.0.0-SNAPSHOT</version> 17 </dependency> 18 </dependencies>
從上面的pom文件可知,
在childA中,javax.servlet的scope為provided
首先解釋下為啥設置為provided:
因為是tomcat中也有servlet-api包,如果默認為compile,即項目在編譯,測試,運行階段都需要這個artifact對應的jar包在classpath中,那么在使用tomcat運行時就會發生了沖突,由於provided只影響編譯和測試階段,在編譯測試階段,我們需要這個artifact對應的jar包在classpath中,而在運行階段,假定目標的容器(比如我們這里的tomcat容器)已經提供了這個jar包,所以無需我們這個artifact對應的jar包了,那么在實際發布時會默認使用第三方web服務器中提供的jar包,而不會使用本jar包。
由於childB直接依賴childA,所以childB在測試編譯階段可引入servlet-api包,程序可以正常跑通,
但是childC依賴B,而childC也是需要childA中的servlet-api包,但是由於provided沒有傳遞性,scope在不指明情況下默認為copmpile,所以childC和childA是間接依賴關系,所以childC無法引用servlet-api包,導致運行報錯,此時需要單獨在childC中加servlet-api依賴包,
1 <modelVersion>4.0.0</modelVersion> 2 <parent> 3 <groupId>com.alice</groupId> 4 <artifactId>Parent</artifactId> 5 <version>1.0.0-SNAPSHOT</version> 6 </parent> 7 <artifactId>childC</artifactId> 8 9 <name>childC</name> 10 <packaging>jar</packaging> 11 12 <dependencies> 13 <dependency> 14 <groupId>com.alice</groupId> 15 <artifactId>childB</artifactId> 16 <version>1.0.0-SNAPSHOT</version> 17 </dependency> 18 <dependency> 19 <groupId>javax.servlet</groupId> 20 <artifactId>javax.servlet-api</artifactId> 21 <version>3.1.0</version> 22 <scope>test</scope> 23 </dependency> 24 </dependencies>
什么是傳遞性依賴(https://blog.csdn.net/lewky_liu/article/details/78145211)
有時候我們在pom.xml文件中引入的依賴,其本身就需要依賴於其他的依賴,這時候我們不需要去考慮這些依賴,Maven會解析各個直接依賴的pom,將那些必要的間接依賴,以傳遞性依賴的形式引入到當前的項目中。
通過傳遞性依賴,我們可以在pom.xml文件中少寫不少的依賴配置
傳遞性依賴的依賴范圍
假如當前項目為A,A依賴於B,B依賴於C。此時稱A對於B是第一直接依賴,B對於C是第二直接依賴,而A對於C是傳遞性依賴。只要知道B在A項目中的scope,就可以知道C在A中的scope。其依賴范圍如下:
表格的第一列是B在A中的依賴范圍,第一行是C在B中的依賴范圍,交叉的格子是C在A中的依賴范圍
當C在B中的scope為test時,A不依賴C,C直接被丟棄
當C在B中的scope為provided時,只有當B在A中的scope也是provided時,A才會依賴C,這時候C在A的scope是provided
當C在B中的scope為compile或runtime時,A依賴C,此時C在A中的scope繼承自B在A的scope。注意,如果C的scope是runtime,B的scope是compile,此時C在A的scope是runtime,而不是compile
參考https://blog.csdn.net/u013704227/article/details/46460913
https://blog.csdn.net/lewky_liu/article/details/78145211