天天看點

10分鐘Maven必學必會: 依賴範圍、繼承、以及dependencyManagement

作者:益柏資料

依賴範圍

Maven 具有以下 6 中常見的依賴範圍,如下表所示。

依賴範圍 描述
compile 編譯依賴範圍,scope 元素的預設值。使用此依賴範圍的 Maven 依賴,對于三種 classpath 均有效,即該 Maven 依賴在上述三種 classpath 均會被引入。例如,log4j 在編譯、測試、運作過程都是必須的。
test 測試依賴範圍。使用此依賴範圍的 Maven 依賴,隻對測試 classpath 有效。例如,Junit 依賴隻有在測試階段才需要。
provided 已提供依賴範圍。使用此依賴範圍的 Maven 依賴,隻對編譯 classpath 和測試 classpath 有效。例如,servlet-api 依賴對于編譯、測試階段而言是需要的,但是運作階段,由于外部容器已經提供,故不需要 Maven 重複引入該依賴。
runtime 運作時依賴範圍。使用此依賴範圍的 Maven 依賴,隻對測試 classpath、運作 classpath 有效。例如,JDBC 驅動實作依賴,其在編譯時隻需 JDK 提供的 JDBC 接口即可,隻有測試、運作階段才需要實作了 JDBC 接口的驅動。
system 系統依賴範圍,其效果與 provided 的依賴範圍一緻。其用于添加非 Maven 倉庫的本地依賴,通過依賴元素 dependency 中的 systemPath 元素指定本地依賴的路徑。鑒于使用其會導緻項目的可移植性降低,一般不推薦使用。
import 導入依賴範圍,該依賴範圍隻能與 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 檔案中 dependencyManagement 的配置導入合并到目前 pom.xml 的 dependencyManagement 中。

多子產品

公司環境中,或者是稍微複雜一點的maven項目,一般會使用多子產品。

父pom檔案定義的dependencies在子子產品中會被繼承,就是說:子子產品無需引用任何包,就擁有了父pom所定義的所有包了。

那麼,為何經常在一些稍微複雜的項目中看到dependencyManagement呢?

這是因為:子子產品可以通過繼承獲得父子產品中聲明的全部依賴,這樣雖然避免了在各個子子產品 POM 中重複進行依賴聲明,但也極有可能造成子子產品中引入一些不必要的依賴。為此 Maven 引入了 dependencyManagement 來對依賴進行管理。

使用dependencyManagement 管理依賴的特點:

  • 在dependencyManagement标簽中聲明的依賴不會自動引入到項目子產品中,隻有通過在dependencies中聲明了同樣的包,才會引入到子產品中。
  • 若dependencies中聲明的包沒有指明版本,則使用dependencyManagement中聲明的版本,否則dependencies聲明的版本将覆寫dependencyManagement的聲明。

這樣,我們既可以從全局管理項目依賴,總體上進行版本統一化管理,又可以為子產品本身排除不需要的依賴,或者進行定制所依賴的版本。

下面這是1個例子,包括2個子產品:ModuleOne和ModuleTwo。

父pom檔案
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>MavenDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>ModuleOne</module>
        <module>ModuleTwo</module>
    </modules>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.9</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.18</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>
                <artifactId>c3p0</artifactId>
                <version>0.9.1</version>
            </dependency>
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.6</version>
            </dependency>
        </dependencies>
    </dependencyManagement>



</project>           
子子產品ModuleTwo pom檔案

父pom聲明了4個dependency,而該子產品根據需要,隻聲明使用其中的1個,即commons-lang包,使用新的版本覆寫了一個,即mysql-connector-jav 8.0.30

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>MavenDemo</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ModuleTwo</artifactId>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
        </dependency>
    </dependencies>

</project>           

繼續閱讀