Maven之scope詳解


Maven中的依賴作用范圍概述

Maven中使用 scope 來指定當前包的依賴范圍和依賴的傳遞性。常見的可選值有:compile, provided, runtime, test, system 等。scope 主要是用在 pom.xml 文件中的依賴定義部分,例如:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.1.RELEASE</version>
            <scope>test</scope>
        </dependency>

scope各種取值詳解

scope取值 有效范圍(compile, runtime, test) 依賴傳遞 例子
compile all spring-core
provided compile, test servlet-api
runtime runtime, test JDBC驅動
test test JUnit
system compile, test

正如上表所示,

compile :為默認的依賴有效范圍。如果在定義依賴關系的時候,沒有明確指定依賴有效范圍的話,則默認采用該依賴有效范圍。

此種依賴,在編譯、運行、測試時均有效。

provided :在編譯、測試時有效,但是在運行時無效。

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

事實上該依賴理論上可以參與編譯,測試,運行等周期。相當於compile,但是在打包階段做了exclude的動作。

例如:servlet-api,運行項目時,容器已經提供,就不需要Maven重復地引入一遍了。

runtime :在運行、測試時有效,但是在編譯代碼時無效。

說實話在終端的項目(非開源,企業內部系統)中,和compile區別不是很大。比較常見的如JSR×××的實現,對應的API jar是compile的,具體實現是runtime的,compile只需要知道接口就足夠了。

例如:JDBC驅動實現,項目代碼編譯只需要JDK提供的JDBC接口,只有在測試或運行項目時才需要實現上述接口的具體JDBC驅動。

另外runntime的依賴通常和optional搭配使用,optional為true。我可以用A實現,也可以用B實現。

test :只在測試時有效,包括測試代碼的編譯,執行。例如:JUnit。

PS: test表示只能在src下的test文件夾下面才可以使用,你如果在a項目中引入了這個依賴,在b項目引入了a項目作為依賴,在b項目中這個注解不會生效,因為scope為test時無法傳遞依賴。

system :在編譯、測試時有效,但是在運行時無效

和provided的區別是,使用system范圍的依賴時必須通過systemPath元素顯式地指定依賴文件的路徑。由於此類依賴不是通過Maven倉庫解析的,而且往往與本機系統綁定,可能造成構建的不可移植,因此應該謹慎使用。

systemPath元素可以引用環境變量。例如:

          <dependency>
            <groupId>javax.sql</groupId>
            <artifactId>jdbc-stdext</artifactId>
            <version>2.0</version>
            <scope>system</scope>
            <systemPath>${java.home}/lib/rt.jar</systemPath>
        </dependency>

scope的依賴傳遞

A–>B–>C。當前項目為A,A依賴於B,B依賴於C。知道B在A項目中的scope,那么怎么知道C在A中的scope呢?

答案是:

當C是test或者provided時,C直接被丟棄,A不依賴C; 否則A依賴C,C的scope繼承於B的scope。

scope的值官方解釋

  • compile

    This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.

  • provided

    This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.

  • runtime

    This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.

  • test

    This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. This scope is not transitive.

  • system

    This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
    import (only available in Maven 2.0.9 or later)
    This scope is only supported on a dependency of type pom in the section. It indicates the dependency to be replaced with the effective list of dependencies in the specified POM’s section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.


免責聲明!

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



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