maven坐标与依赖

maven坐标与依赖

 2016-10-18 |   Visit count

坐标

在maven中,任何构件都有明确定义的坐标。这些坐标是通过一些元素定义的,下面是nexus-indexer的坐标定义:

1
2
3
4
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packing>jar</packing>

groupId:定义当前maven项目隶属的实际项目,一般由公司前缀+隶属项目名称组成

artifactId:定义当前maven项目模块,一般由隶属项目名称+当前maven模块名称组成

version:版本号

packing:打包方式。有jar,war等,默认为jar classifier:定义构件输出的一些附属构件。本例主构件输出nexus-indexer-2.0.0.jar,附属构件比如有:nexus-indexer-2.0.0-javadoc.jar,nexus-indexer-2.0.0-source.jar等

依赖配置

除了上面的基本坐标定义,依赖还可以包含:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<project>
    ...
    <dependency>
        <dependency>
            <groupId>... </groupId>
            <artifactId>... </artifactId>
            <version>... </version>
            <type>... </type>
            <scope>... </scope>
            <optional>... </optional>
            <exclusions>
                <exclusion>
                ...
                </exclusion>
            ...    
            </exclusions>
        </dependency>
        ...
    </dependency>
    ...
</project>

type:依赖的类型,对应坐标中的packing,默认为jar,一般不用声明

scope:依赖的范围

optional:标记依赖是否可选,若为true则为可选依赖。可选依赖不能传递

exclusions:用来排除传递性依赖

依赖范围

在一个maven项目中主要有三个classpath:编译classpath,测试classpath,运行时classpath。下表列出了依赖范围和classpath的关系:

依赖范围
(Scope)
对于编译
classpath有效
对于测试
classpath有效
对于运行时
classpath有效
例子
compilespring-core
test××JUnit
provided×servlet-api
runtime×JDBC驱动实现
system×本地的,Maven仓库外的 类库文件

compile:编译依赖范围

test:测试依赖范围

provided:已提供依赖范围

runtime:运行时依赖范围

system:系统依赖范围

import:导入依赖范围

传递性依赖

现有pom如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<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.juven.mvnbook.account</groupId>
    <artifactId>account-email</artifactId>
    <name>Account Email</name>
    <version>1.0.0-SNAPSHOT</version>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.7</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.icegreen</groupId>
            <artifactId>greenmail</artifactId>
            <version>1.5.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

上面的xml中有一个org.springframework:spring-core.4.3.3.RELEASE.jar依赖。在中央仓库查看其xml,会发现其还包含了:

1
2
3
4
5
6
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
    <scope>compile</scope>
</dependency>

该依赖的范围为compile,而spring-core依赖没有直接声明依赖范围,默认为compile。现在account-email有一个compile范围的spring-core依赖,spring-core有一个compile范围的comms-logging依赖,所以comms-logging会成为account-email的compile范围的传递性依赖

现假设A依赖于B,B依赖于C,那么A相对于B是第一直接依赖,B相对于C是第二直接依赖,A相对于C是传递性依赖,其依赖范围按下表定义:

compiletestprovidedruntime
compilecompilecompile
testtesttest
providedprovidedprovidedprovided
runtimeruntimeruntime

表中,第一列是第一直接依赖范围,第一行是第二直接依赖范围,交叉部分是最终传递性依赖范围。

依赖调解

依赖调解有两个原则:

1.路径最近的优先

现在有如下两个依赖:

A → B → C → X(1.0.0)

A → B → X(1.2.1)

A有两个版本的传递性依赖X,因为X(1.2.1)路径较短,所以最终X(1.2.1)会被解析使用。

2.第一声明者优先

现在有如下两个依赖:

A → B → X(1.0.0)

A → B → X(1.2.1)

两个版本X的依赖路径一样长,这时候谁被解析取决于谁先定义!

排除依赖

使用compile:tree查看依赖树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ account-email ---
[INFO] com.juven.mvnbook.account:account-email:jar:1.0.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.3.3.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.2:compile
[INFO] +- org.springframework:spring-beans:jar:4.3.3.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.3.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:4.3.3.RELEASE:compile
[INFO] +- org.springframework:spring-context-support:jar:4.3.3.RELEASE:compile
[INFO] +- javax.mail:mail:jar:1.4.7:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- junit:junit:jar:4.7:test
[INFO] \- com.icegreen:greenmail:jar:1.5.2:test
[INFO]    +- com.sun.mail:javax.mail:jar:1.5.6:test
[INFO]    \- org.slf4j:slf4j-api:jar:1.7.21:test

如上所述的,spring-core隐式依赖于commons-logging,如果不想传递此依赖,可以为spring-core添加exclusions元素:

1
2
3
4
5
6
7
8
9
10
11
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.3.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

再次执行dependency:tree命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ account-email ---
[INFO] com.juven.mvnbook.account:account-email:jar:1.0.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.3.3.RELEASE:compile
[INFO] +- org.springframework:spring-beans:jar:4.3.3.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:4.3.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:4.3.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:4.3.3.RELEASE:compile
[INFO] +- org.springframework:spring-context-support:jar:4.3.3.RELEASE:compile
[INFO] +- javax.mail:mail:jar:1.4.7:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- junit:junit:jar:4.7:test
[INFO] \- com.icegreen:greenmail:jar:1.5.2:test
[INFO]    +- com.sun.mail:javax.mail:jar:1.5.6:test
[INFO]    \- org.slf4j:slf4j-api:jar:1.7.21:test

可发现spring-core已经不依赖于commons-logging了,当然这里只是单纯演示排除依赖,commons-logging对于Spring框架是必须的。

归类依赖

在上述的pom中,spring的版本都为4.3.3.RELEASE版本,而且对于一个框架来说,其各个模块的版本一般都是一样的,这里我们可以统一声明其版本,然后引用即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<properties>
    <springframework.version>4.3.3.RELEASE</springframework.version>
</properties>
...
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${springframework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>${springframework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${springframework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${springframework.version}</version>
</dependency>

这样在以后更新spring版本的时候,只需要修改properties即可。

优化依赖

除了使用dependency:tree命令外,还可使是dependency:list查看所有依赖:

dependency:list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ account-email ---
[INFO] 
[INFO] The following files have been resolved:
[INFO]    org.springframework:spring-beans:jar:4.3.3.RELEASE:compile
[INFO]    org.springframework:spring-context-support:jar:4.3.3.RELEASE:compile
[INFO]    org.slf4j:slf4j-api:jar:1.7.21:test
[INFO]    junit:junit:jar:4.7:test
[INFO]    com.sun.mail:javax.mail:jar:1.5.6:test
[INFO]    com.icegreen:greenmail:jar:1.5.2:test
[INFO]    commons-logging:commons-logging:jar:1.2:compile
[INFO]    org.springframework:spring-aop:jar:4.3.3.RELEASE:compile
[INFO]    javax.activation:activation:jar:1.1:compile
[INFO]    javax.mail:mail:jar:1.4.7:compile
[INFO]    org.springframework:spring-core:jar:4.3.3.RELEASE:compile
[INFO]    org.springframework:spring-context:jar:4.3.3.RELEASE:compile
[INFO]    org.springframework:spring-expression:jar:4.3.3.RELEASE:compile

使用dependency:analyze分析依赖:

1
2
3
4
5
6
7
[INFO] <<< maven-dependency-plugin:2.8:analyze (default-cli) @ account-email <<<
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:analyze (default-cli) @ account-email ---
[WARNING] Unused declared dependencies found:
[WARNING]    org.springframework:spring-core:jar:4.3.3.RELEASE:compile
[WARNING]    org.springframework:spring-beans:jar:4.3.3.RELEASE:compile
[INFO] ------------------------------------------------------------------------

《Maven实战》读书笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值