您的位置:首页 > 其它

在Mac OS X + Idea下搭建Maven项目 -- Maven的依赖管理

2018-01-07 18:09 381 查看
上一篇博文讲到如何安装maven,这篇算是它的续篇,总结下maven是如何管理依赖的。

maven强大之处就是管理依赖。通过依赖传递,依赖继承,以及pom导入,可以轻松实现依赖的版本管理。通过依赖scope实现在不同的生命周期时段,加入依赖。

如下是一个最简单的为当前项目添加依赖的示例:

IntelliJ Idea > Preferences… > Build, Execution, Deployment > Build Tools > Maven

Importing一栏,将”Import Maven projects automatically” 勾选上。如果这一栏没有勾选的话,Idea会在右上角有个漂浮提示,也可以从这个提示那里点击开启。

接下来,往pom.xml里添加一条依赖,IDE会自动将此依赖添加到External Libraries里面。

<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>


#### 依赖传递 ####

比如我在pom.xml里加上了junit. 而junit要依赖于hamcrest-core。但是我不用再添加对于hamcrest-core的依赖,maven会自动做掉,于是我的External Libraries里面不仅有junit,还有hamcrest-core.

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>


#### 依赖scope ####

compile: 默认的scope,如果在dependency节点里没有写scope,那么它默认是compile

provided: JDK/容器在运行时会产生/提供这个依赖

runtime: 依赖仅在运行时需要,在编译时是不需要的

test: 依赖仅用于测试,并不用于真正的appliation,比如添加junit依赖时,就可以为它加上scope = test,前提是application本身真的不需要用到junit

system: 貌似已经弃用了…

import: 导入别的pom的dependencyManagement部分

#### 依赖继承 ####

依赖继承有两个重要作用:

将子项目的公用依赖加入到父项目里,化简子项目的pom.xml

通过父项目的dependencyManagement里申明的版本号来管理所用依赖的版本

如下例子来自maven官方文档。Project A是父项目。Project B是A的子项目,所以B继承了A申明在dependencyManagement段落里的依赖,即:a-1.2,b-1.0,c-1.0,d-1.2。

但是由于B自己本身有定义对于a和c的依赖,所以对于依赖a, B会用自己本身定义的a-1.0。对于依赖c,B里面并未定义版本,所以maven会上溯至父亲A中找到对c的版本定义,所以是c-1.0。对于依赖b,它没有定义在B自己的pom里,所以继承自父亲A,b-1.0。对于依赖d,父亲A里有,自己的dependencyManagement也有,优先选用自己的,所以是c-1.0。

<parent>
<artifactId>A</artifactId>
<groupId>maven</groupId>
<version>1.0</version>
</parent>


Project A的pom.xml:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>A</artifactId>
<packaging>pom</packaging>
<name>A</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>b</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>d</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>


Project B的pom.xml:

<project>
<parent>
<artifactId>A</artifactId>
<groupId>maven</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<name>B</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>d</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>


一般来说,将dependencyManagement置于顶层项目的pom.xml文档中,用于依赖包的版本控制,以确保各个子项目中用到的依赖都是相同的版本。dependencyManagement仅申明依赖和版本,并不实际下载依赖包。

当子项目中的dependencies里有申明某依赖且没有版本号时,maven会上溯,直到在上层pom里找到该依赖的版本。子项目不用显示地写依赖的版本,以达到统一管理依赖版本的目的。

如果想要将依赖传递下去(传给子项目,或者传给那些import 这个pom的项目),则把依赖定义在dependencyManagement部分。如果不想用父亲/import进来的pom里定义的依赖版本,则在dependency部分申明特定版本号的依赖。否则,就应该在dependency部分仅申明依赖,不申明依赖版本,统一用父亲/import进来的pom里定义的依赖版本,来实现版本管理。

#### 依赖导入 ####

在大型项目中,依赖导入使用的更多。这里用依赖导入来实现刚刚在依赖继承小节实现的B继承A的目的。

在B的pom.xml的dependencyManagement部分,import A的pom:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>maven</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<name>B</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>maven</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>d</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>a</artifactId>
<version>1.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>c</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>


在大型项目中,某些模块依赖某些项目是非常常见的,为了使这些模块的依赖项目版本统一,使用依赖继承+依赖导入是一种非常好的实践。在根pom中指明依赖版本,在模块中导入根pom,统一使用根pom定义的版本。将来依赖版本有更新时,只用更改根pom里的版本号即可。这一点颇有设计模式的味道…

首先在根pom–bom(bill of material)的dependencyManagement部分申明依赖project1和project2,版本的话则引用properties部分定义的变量。并且根pom里指明子项目parent。

<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>com.test</groupId>
<artifactId>bom</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<project1Version>1.0.0</project1Version>
<project2Version>1.0.0</project2Version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>project1</artifactId>
<version>${project1Version}</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>project2</artifactId>
<version>${project1Version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>parent</module>
</modules>
</project>


接下来在parent项目的pom-dependencyManagement部分,定义了一些外部依赖,并指定了版本。而且还定义了子项目project1和project2.

<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>
<parent>
<groupId>com.test</groupId>
<version>1.0.0</version>
<artifactId>bom</artifactId>
</parent>

<groupId>com.test</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>project1</module>
<module>project2</module>
</modules>
</project>


接下来是project1和project2的pom,它们的pom里只申明了dependency而并未申明版本,因为要统一用父亲parent pom里定义的依赖版本。

<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>
<parent>
<groupId>com.test</groupId>
<version>1.0.0</version>
<artifactId>parent</artifactId>
</parent>
<groupId>com.test</groupId>
<artifactId>project1</artifactId>
<version>${project1Version}</version>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
</project>


<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>
<parent>
<groupId>com.test</groupId>
<version>1.0.0</version>
<artifactId>parent</artifactId>
</parent>
<groupId>com.test</groupId>
<artifactId>project2</artifactId>
<version>${project2Version}</version>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
</dependencies>
</project>


最后,当别的项目要引用project1和project2时,直接在dependencyManagement部分导入根pom(即bom),然后在dependencies部分申明要用到的依赖。不用指明版本,因为maven会取根pom(即bom)里在properties部分定义的版本。

<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>com.test</groupId>
<artifactId>use</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>project1</artifactId>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>project2</artifactId>
</dependency>
</dependencies>
</project>


maven官方文档链接:

https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息