依賴范圍(scope)不同選項的區(qū)別
依賴范圍參數(shù)的作用是控制依賴在不同階段與classpath的關(guān)系,具體區(qū)別如下圖所示。

表中沒有列出的值是import,這個選項是用于引入dependencyManagement,下文會有介紹。
依賴調(diào)解,調(diào)解同一依賴的不同版本
假設(shè)你的項目有如下的依賴樹
POM
|-- A
| `-- B 1.0
|-- C
| `-- D
| `-- B 2.0
`-- E
`-- B 3.0
POM同時依賴了B的1.0和2.0版本,可Maven是不會重復引入相同坐標的依賴的,那么究竟哪個版本會生效呢?
Maven對于依賴的調(diào)解遵循兩個基本原則:
- 1 依賴路徑長度短者優(yōu)先;
- 2 如果依賴路徑長度相同,則后聲明優(yōu)先。
所以根據(jù)1,2.0版本被排除,根據(jù)2,3.0版本被實際引入。
如果你自己明確知道該引入哪個版本的B,那么直接在POM中聲明B依賴就好了,因為這時的依賴路徑是最短了。
可選依賴(optional)含義
可選依賴的作用就是聲明該依賴不被傳遞依賴。
POM
`-- A
`-- B(optional)
這里B不會被引入。
Super POM(Project Object Model)
Super POM是Maven自帶的全局POM文件,所有的POM文件都默認繼承了Super POM。其中定義了各種默認配置,以簡化POM文件的編寫。下面是Maven 3.5.4的Super POM的核心部分。
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<directory>${project.basedir}/target</directory>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>${project.basedir}/src/test/resources</directory>
</testResource>
</testResources>
...
Super POM中定義了中央依賴倉庫、中央插件倉庫,以及各種文件夾的默認路徑。
POM繼承
如果你的項目有多個模塊,通常每個模塊之間會有一些相同的公共的依賴,你可以把依賴聲明在模塊各自的POM中,如下所示。
.
|-- mod A
| `-- pom.xml
| `-- P(1.0)
`-- mod B
`-- pom.xml
`-- P(1.0)
這樣A模塊和B模塊都依賴了P,但是如果有天你想要修改P的版本,又希望A,B模塊依賴的P版本相同,那就得同時修改POM-A和POM-B,太不優(yōu)雅了。
所以Maven提供了POM繼承功能,讓我們可以吧公共的依賴抽取出來。
.
|-- pom.xml (父POM)
| `-- P(1.0)
|-- mod A
| `-- pom.xml
`-- mod B
`-- pom.xml
做法如上,在父POM中聲明依賴P,在AB模塊的POM中聲明對父POM的繼承,便能實現(xiàn)AB模塊對P依賴的引入。
AB模塊中加入下面一段,便能實現(xiàn)對父POM的繼承。
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<relativePath>../pom.xml</relativePath>
</parent>
relativePath的默認值即是‘../pom.xml’,可以省略。
值得一提的是,這里父POM并不需要知道子POM的信息。
總之,有了繼承,子模塊就能擁有父模塊同樣的依賴。
POM聚合
假設(shè)你的項目有多個模塊,通常每個模塊需要各自單獨構(gòu)建,如果想要所有模塊能同時構(gòu)建,則需要使用Maven的聚合功能。
使用聚合同樣需要建一個父POM
.
|-- pom.xml (父POM)
|-- A
| `-- pom.xml
`-- B
`-- pom.xml
父POM內(nèi)容如下:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>A</module>
<module>B</module>
</modules>
</project>
其中packaging必須是pom,modules中聲明需要聚合的子模塊。
與繼承相反,子POM中不需要父POM的信息。
總之,有了聚合,所有對父模塊執(zhí)行的Maven命令,同樣會對子模塊執(zhí)行。
依賴管理(dependencyManagement)是什么
在前面講繼承的時候,我們通過父POM使得AB兩個模塊都擁有了依賴P,但是如果我們現(xiàn)在添加一個模塊C,模塊C并不需要依賴P,只需要父POM中的其他配置和依賴,該怎么辦呢?
這就要用到dependencyManagement這個配置了,dependencyManagement與dependencies元素不同在于并不會真的引入依賴,只是指定依賴的版本。
做法是在父POM中添加dependencyManagement配置
<dependencyManagement>
<dependencies>
<dependency>
<groupId>groupabc</groupId>
<artifactId>p</artifactId>
<version>1.0</version>
</dependency>
</dependencyManagement>
然后在AB模塊的POM中添加如下,注意不含版本信息。
<dependencies>
<dependency>
<groupId>groupabc</groupId>
<artifactId>p</artifactId>
</dependency>
</dependencies>
如此一來,AB模塊都引入了依賴p的v1.0,而模塊C沒有引入依賴p。
另外還有pluginManagement與此類似,不過是針對插件而已。
參考文獻
Introduction to the Dependency Mechanism
轉(zhuǎn)載請保留原文地址:Maven用戶都應(yīng)該知道的一些事:關(guān)于依賴的常見問題