一个依赖声明能够包含下面元素:java
<dependencies> <dependency> <groupId></groupId> <artifactId></artifactId> <version></version> <type></type> <scope></scope> <optional></optional> <exclusions> <exclusion> </exclusion> </exclusions> </dependency> </dependencies>
groupId、artifactId、version
依赖的基本坐标。
type
:依赖的类型,对应于项目坐标定义的packaging
,默认:jar
。
scope
:依赖的范围。
optional
:标志依赖是否可选,true/false
。
exclusions
:用来排除传递性依赖。spring
依赖范围是用来控制依赖于三种classpath
(编译classpath
、测试classpath
、运行classpath
)的关系。
Maven
的依赖范围有以下几种:
compile
:编译依赖范围,默认值,对三种classpath都有效。
test
:测试依赖范围,只对测试classpath
有效,典型例子如:Junit
provided
:已提供依赖范围,对编译和测试classpath
有效,但在运行时无效,典型例子如:servlet-api
,运行时由容器提供。
runtime
:运行时依赖范围,对测试和运行classpath
有效,编译主代码时无效,典型例子如:JDBC
驱动实现,编译时只须要JDK
提供的JDBC
接口,运行才须要具体的实现。
system
:系统依赖范围,对编译和测试classpath
有效,但在运行时无效。使用该范围时,必须经过systemPath
元素指定依赖的路径。sql
<dependency> <groupId>javax.sql</groupId> <artifactId>jdbc-stdext</artifactId> <version>2.0</version> <scope>system</scope> <systemPath>${java.home}/lib/rt.jar</systemPath> </dependency>
import
:导入依赖范围,该范围不会对三种classpath
产生实际应用,会将目标POM
中的dependencyManagement
配置导入合并到当前POM
的dependencyManagement
元素中。
api
Maven
的传递性依赖是指不须要考虑你依赖的库文件所须要依赖的库文件,可以将依赖模块的依赖自动的引入。ide
依赖的范围不只能够控制依赖与三种classpath
的关系,还会对传递性依赖产生影响。假设A依赖于B,B依赖于C,则说A对于B是第一直接依赖,B对C是第二直接依赖,A对于C是传递依赖。第一直接依赖范围和第二直接依赖范围决定了传递性依赖的范围,其结果以下:
测试
第二直接依赖范围是`compile`时,传递性依赖范围与第一直接依赖范围一致; 第二直接依赖范围是`test`时,依赖不会得以传递; 第二直接依赖范围是`provided`时,只传递第一直接依赖范围也为provided的; 第二直接依赖范围是`runtime`时,传递性依赖的范围与第一直接依赖范围一致,`compile`例如,此时的传递性依赖范围为`runtime`。
通常状况下,只关心项目的直接依赖,而不关心直接依赖引入的传递性依赖,但当传递性依赖出现问题时,须要知道该传递性依赖是怎么引进来的。
Maven
依赖调解第一原则:路径最近者优先
,如:A->B->C->X(1.0)、A->D-X(2.0),则X的2.0版本会被解析使用;
Maven
依赖调解第二原则:第一声明者优先
,如:A->B->X(1.0)、A->D->X(2.0),若B的依赖声明在D以前,则使用X的1.0版本,不然使用X的2.0版本。优化
假设有下面的依赖关系:A->B、B->X(可选)、B->Y(可选),因为X和Y是可选的,因此依赖不会传递,X和Y不会对A有任何影响。spa
可选依赖的必要性:项目B实现2种特性,特性一依赖于X,特性二依赖于Y,并且这两个特性是互斥的,用户不可能同时适用这两个特性,这时候可选依赖就有用了。
原则上说,是不该该使用可选依赖的,根据面向对象的单一职责性原则,该原则一样适用于Maven项目的规划。code
1)排除依赖对象
传递性依赖会给项目隐式的引入不少依赖,这极大的简化了项目依赖的管理,可是有时某些依赖会带来问题,这时须要把带来问题的依赖排除掉。
2)归类依赖
来自同一个项目的不一样模块,其版本号应该是相同的,如springframework
项目有spring-core
、spring-beans
模块,对这些模块的版本号经过属性定义,再进行引用,这样能够进行版本的总体升级:
<properties> <springframework.version>4.3.13.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>
3)优化依赖
去掉多余的依赖,显示声明某些必要的依赖。
经过mvn dependency:list
查看项目已解析的依赖
经过mvn dependency:tree
查看项目的依赖树