坐标五元素:groupId、artifactId、version、packaging(可选)、classifier(不能直接定义)
坐标五元素指的不是<dependency>中的而是声明当前项目使用的。
version支持范围自动选择
[x, y]
从版本x到版本y,包含版本x和版本y。
(x, y)
从版本x到版本y,不包含版本x和版本y。
[x, y)
从版本x到版本y,包含版本x,不包含版本y。
(x, y]
从版本x到版本y,不包含版本x,包含版本y。
[x, )
所有比版本x更高的版本,包含版本x。
(, x]
所有比版本x更低的版本,包含版本x。
[x, y), (y, )
从版本x到所有比版本y更高的版本,包含版本x,但不包含版本y。
如果你使用Maven来管理依赖项,那么可能在引入Twitter4J API的时候,使用过如示例5-1所示的语法。
示例5-1:通过Maven指定依赖项的版本范围
<dependency>
<groupId>org.twitter4j</groupId>
<artifactId>twitter4j-core</artifactId>
<version>[4.0, )</version>
</dependency>
示例5-1使用了语义版本控制(稍后将详细介绍),表示你要引入依赖项的4.0.0及更高的小版本。如果你最初创建项目时使用的是Twitter4J API的4.0.0版本,那么它就是构件中使用的版本。如果Twitter4J发布了新的4.0.1版本,那么新的构件将使用该版本,对于范围中的其他版本(例如4.0.2和4.0.15)也一样。但是,如果Twitter4J发布了新的4.1.0或5.0.0版本,则不会被包含在构件中,因为这超出了指定的范围。使用这种语义背后的理论依据是,升级补丁不会改变依赖项的API或者语义行为,但会包含持续性的安全和bug修复。
packaging 定义Maven项目的打包方式。打包方式通常与所生成构建的文件拓展名对应。不定义时默认是jar。
classifier 用来帮助定义构建输出的一些附属构建。附属构建与主构建对应,如主构件是nexus-indexer-2.0.0 jar,该项目还有一些附属构建,nexus-indexer-2.0.0-javadoc.jar 、nexus-indexer-2.0.0-sources.jar这样一些构建。classifier不能直接定义,而是由附加的插件帮助生成的。
项目构建的文件名是与坐标相对应的,一般的规则为 artifactId-version[-classifier].packaging
依赖声明元素:
groupId、artifactId和version
type 对应于坐标定义的packaging
scope 依赖范围
optional 依赖是否可选
exclusion 用来排除传递性依赖
Maven有以下几种依赖范围scope: maven scope含义的说明_雨中漫步的技术博客_51CTO博客
compile:编译依赖范围(默认),使用此依赖范围对于编译、测试、运行三种 classpath 都有效,即在编译、测试和运行的时候都要使用该依赖jar包;
test:测试依赖范围,从字面意思就可以知道此依赖范围只能用于测试classpath,而在编译和运行项目时无法使用此类依赖,典型的是JUnit,它只用于编译测试代码和运行测试代码的时候才需要;
provided:此依赖范围,对于编译和测试classpath有效,而对运行时无效;
runtime:运行时依赖范围,对于测试和运行classpath有效,但是在编译主代码时无效,典型的就是JDBC驱动实现;
system:系统依赖范围,使用system范围的依赖时必须通过systemPath元素显示地指定依赖文件的路径,不依赖Maven仓库解析,所以可能会造成建构的不可移植,谨慎使用。
import:导入依赖范围。该范围不会对三种classpath产生实际的影响。
依赖范围与classpath的关系
依赖范围影响传递依赖
可选依赖
<optional>true<optional> 不会传递
排除依赖
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId>可以用通配符 *</artifactId>
</exclustion>
</exclusions>
依赖调解
当两个依赖路径上有两个版本的依赖X时,有以下两个依赖调解原则:
第一原则:路径最近者优先;
第二原则:路径长度一样时,第一声明者优先。
如果同package和同类名的两个类出现在两个不同的依赖上,会先加载先声明的那一个
可以使用maven helper
优化依赖
使用这个插件Apache Maven Dependency Plugin – Introduction
使用dependency:list和dependency:tree 帮助我们详细了解项目中所有依赖的具体信息。
只打出指定groupId和artifactId的依赖关系
mvn dependency:tree -Dverbose -Dincludes=groupId:artifactId
使用dependency:analyze工具可以帮助分析当前项目的依赖。
analyze的结果中包含了两部分:
Used undeclared dependencies:项目中使用但未显式声明的依赖。这种依赖意味着潜在的风险;
Unused declared dependencise:项目中未使用的,但显式声明的依赖。对于这种依赖不能直接删除,因为analyze只会分析编译和测试需要的依赖,其他依赖它无法发现,因此需要仔细分析。
-
使用mvn dependency:analyze-only命令用于检测那些声明了但是没被使用的依赖,如有有一些是你自己声明的,那尽量去掉
-
使用mvn dependency:analyze-duplicate命令用来分析重复定义的依赖,清理那些重复定义的依赖