依賴範圍
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>