scope為provided


 

以下面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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM