Maven scope依賴范圍詳解


1、Maven介紹

  Maven 翻譯為"專家"、"內行",是 Apache 下的一個純 Java 開發的開源項目。基於項目對象模型(縮寫:POM)概念,Maven利用一個中央信息片斷能管理一個項目的構建、報告和文檔等步驟。

       Maven是一個管理工具,可以對 Java 項目進行構建、依賴管理。Maven 曾是 Jakarta 項目的子項目,現為由 Apache 軟件基金會主持的獨立 Apache 項目,

 

2、Maven特點

  1.  項目設置遵循統一的規則
  2.  任意工程中共享
  3.  依賴管理包括自動更新
  4.    一個龐大且不斷增長的庫
  5.    可擴展,能夠輕松編寫 Java 或腳本語言的插件
  6.    只需很少或不需要額外配置即可即時訪問新功能
  7.    基於模型的構建 − Maven能夠將任意數量的項目構建到預定義的輸出類型中,如 JAR,WAR 或基於項目元數據的分發,而不需要在大多數情況下執行任何腳本
  8.    項目信息的一致性站點 − 使用與構建過程相同的元數據,Maven 能夠生成一個網站或PDF,包括您要添加的任何文檔,並添加到關於項目開發狀態的標准報告中
  9.    發布管理和發布單獨的輸出 − Maven 將不需要額外的配置,就可以與源代碼管理系統(如 Subversion 或 Git)集成,並可以基於某個標簽管理項目的發布。也可以發布到分發位置供其他項目使用。包含其他依賴和文檔的歸檔,或者作為源代碼發布。
  10.    向后兼容性 − 您可以很輕松的從舊版本 Maven 的多個模塊移植到 Maven 3 中
  11.    子項目使用父項目依賴時,正常情況子項目應該繼承父項目依賴,無需使用版本號

 

3、Maven scope依賴范圍詳解

   Maven的生命周期存在編譯、測試、運行這些過程,那么顯然有些依賴只用於測試,比如junit;有些依賴編譯用不到,只有運行的時候才能用到,比如mysql的驅動包在編譯期就用不到(編譯期用的是JDBC接口),而是在運行時用到的;還有些依賴,編譯期要用到,而運行期不需要提供,因為有些容器已經提供了,比如servlet-api在tomcat中已經提供了,我們只需要的是編譯期提供而已。總結說來,在POM 4中,<dependency>中還引入了<scope>,它主要管理依賴的部署。大致有compile、provided、runtime、test、system等幾個。

  1. compile:默認的scope,運行期有效,需要打入包中
  2. provided:編譯期有效,運行期不需要提供,不會打入包中
  3. runtime:編譯不需要,在運行期有效,需要導入包中。(接口與實現分離)
  4. test:測試需要,不會打入包中
  5. system:非本地倉庫引入、存在系統的某個路徑下的jar。(一般不使用)

 

3.1 compile模式(編譯范圍)

  默認就是compile,什么都不配置也就是意味着compile。compile表示被依賴項目需要參與當前項目的編譯,當然后續的測試,運行周期也參與其中,是一個比較強的依賴。打包的時候通常需要包含進去.

  該依賴需要參與當前項目的編譯、測試、運行、打包

 

 

3.2 compile模式(運行時范圍)

  runntime表示被依賴項目無需參與項目的編譯,不過后期的測試和運行周期需要其參與。與compile相比,跳過編譯而已.

  比如,你可能在編譯的時候只需要JDBC API JAR,而只有在運行的時候才需要JDBC驅動實現。

  編譯時該包不參與,運行時參與

 

3.3 test 模式(測試范圍)

  test范圍依賴 在一般的編譯和運行時都不需要,它們只有在測試編譯和測試運行階段可用。比如

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>test</scope>
</dependency>

  

 3.4 provided(已提供范圍)

  provided 表明該依賴已經提供,故只在未提供時才被使用,

  應用場景是你定義了一個Servlet,此刻得需要Servlet-api.jar 才能編譯成功,但是當你達成war 包時,你並不想將 Servlet-api.jar 包進去,因為Tomcat等容器會提供

  跟compile 類似,說明JDK、容器或使用者會提供這個依賴,如Servlet.jar

  這個依賴只作用在** 編譯和測試,該依賴會由系統組件提供,不需手動添加,只存在編譯、運行、測試階段,打包是不用包進去,打包階段做了exclude**動作

  provided意味着打包的時候可以不用包進去,別的設施(Web Container)會提供。

  阿里開發規范文檔:如果依賴其它二方庫,盡量是 provided 引入,讓二方庫使用者去依賴具體版本號log 具體實現,只依賴日志框架

  例如 : 添加<scope>provided</scope>,因為provided表明該包只在編譯和測試的時候用,所以,當啟動tomcat的時候,就不會沖突了

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>servlet-api</artifactId>
	<version>3.0-alpha-1</version>
	<scope>provided</scope>
</dependency>

  

3.5 system (系統范圍)

  被依賴項不會從maven倉庫下載,而是從本地系統指定路徑下尋找,需要 systemPath 屬性

  system范圍依賴與provided 類似,但是你必須顯式的提供一個對於本地系統中JAR 文件的路徑,這么做是為了允許基於本地對象編譯,而這些對象是系統類庫的一部分。這樣的構件應該是一直可用的,Maven 也不會在倉庫中去尋找它

    從參與度來說,與provided相同,不過被依賴項不會從maven倉庫抓,而是從本地文件系統拿,一定需要配合systemPath屬性使用,例如:

 

  一、方式1.dependency 本地jar包,如果沒有建私服,可以在pom.xml中通過文件方式引

<dependency>
	<!--自定義-->
	<groupId>com.im</groupId>  
	<!--自定義-->
	<artifactId>sdk</artifactId>    
	<!--自定義-->
	<version>1.0</version> 
	<!--system,類似provided,需要顯式提供依賴的jar以后,Maven就不會在Repository中查找它-->
	<scope>system</scope> 
	<!--項目根目錄下的lib文件夾下-->
	<systemPath>${basedir}/lib/sdk-1.0.jar</systemPath> 
</dependency> 

  

  二、方式2.編譯階段指定外部lib

<plugin>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.3.2</version>
	<configuration>
	<source>1.8</source>
	<target>1.8</target>
	<encoding>UTF-8</encoding>
	<compilerArguments>
	<!--指定外部lib-->
	<extdirs>lib</extdirs>
	</compilerArguments>
	</configuration>
</plugin>

  

  三、方式3.0 將外部jar打入本地maven倉庫

  mvn install:install-file -Dfile=sdk-1.0.jar -DgroupId=com.im -DartifactId=sdk -Dversion=1.0 -Dpackaging=jar

 

  四、方式3.1 引入jar包

<dependency>
	<groupId>com.im</groupId>
	<artifactId>sdk</artifactId>
	<version>1.0</version>
</dependency>

  

  五、maven預定義內置屬性

${basedir}表示項目根目錄,即包含pom.xml文件的目錄;
${version}表示項目版本;
${project.basedir}同${basedir};
${project.baseUri}表示項目文件地址;
${maven.build.timestamp}表示項目構件開始時間;
${maven.build.timestamp.format}表示屬性${maven.build.timestamp}的展示格式,默認值為yyyyMMdd-HHmm,可自定義其格式

  

 

4、scope 的傳遞依賴

  A -> B -> C, 當前項目 A,A依賴於B,B依賴於C,知道B在 A中的scope,怎么知道 C在 A 中的 scope

  即,A需不需要 C的問題,本質由 C在B中的scope決定

  當 C 在 B 中的scope 是test 或 provided 時,C 直接被丟棄,A不依賴C

  否則 A 依賴 C,C的scope 繼承與B 的scope

 


免責聲明!

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



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