Maven坐标和依赖(三)
接下来介绍一下Maven的坐标和依赖。
1. Maven坐标
依赖的底层基础就是坐标。在实际生活中我们可以将地址看成一种坐标。而Maven为构件引入坐标的概念。以前当我们需要Spring Framework依赖的时候,就回去Spring官网查找,当需要log4j的依赖时,我们又回去Apache网站查找,这样就花费大量的时间在搜索、浏览网页上。现在Maven定义了一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识。Maven坐标元素包括:groupId, artifactId, version, packaging, classifier。
2. 坐标详解
1)groupId: 定义当前Maven项目隶属的实际项目。groupId的表示方式与Java报名的表示方式类似,通常与域名反向一一对应。如:org.springframework.
2)artifactId: 该元素定义实际项目的一个Maven项目(模块),推荐使用实际项目名称作为artifactId的前缀。如:spring-core. 默认情况下Maven生成的构件会以artifactId作为开头,如spring-core-3.1.0.jar。
3)version: 该元素定义Maven项目当前所处的项目的版本。
4)packaging: 该元素定义Maven项目的打包方式。当不定义packaging的时候,Maven会使用默认值jar。
5)classifier: 该元素用来帮助定义构建输出的一些附属软件。
以上5个元素中,groupId、artifactId、version是必须定义的,packaging是可选的,而classifier是不能直接定义的。
3. 依赖配置
<project> <dependencies> <dependency> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <type>...</type> <scope>...</scope> <optional>...</optional> <exclusions> <exclusion> ... </exclusion> </exclusions> </dependency> </dependencies> </project>
每个依赖都包括的元素有:
groupId、artifactId和version:依赖的基本坐标。
type: 依赖的类型,对应于项目坐标定义的packagin。大多情况下不必声明。
scope: 依赖的范围。
optional: 标记依赖时候可选。
exclusions: 用来配出传递性依赖。
4. 依赖范围
1)compile:编译依赖范围。该依赖对于编译、测试、运行三种classpath都有效。如spring-core。
2)test:测试依赖范围。只对测试范围classpath有效。经典的例子是JUnit。
3)provided:已提供依赖范围,对编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,在编译和测试项目的时候需要该依赖,但是在运行项目时,由于容器已经提供,就不要重复引入。
4)runtime:运行时依赖。对于测试和运行classpath有效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口。
5)system:系统依赖范围。与classpath的关系和provided一样。
6)import:导入依赖范围。该依赖范围不会对三种classpath产生实际的影响。
5. 依赖的传递性
顾名思义,很多人都知道A->B, B->C,那么A->C.但是在Maven中传递的范围是会改变的,这个由maven自身处理。如下图:
第一列为第一依赖,第一行为第二依赖,单元格内为传递范围。
compile | test | provided | runtime | |
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
6. 依赖调解
如果有多个相同的依赖,Maven会根据一定的规则来确定: 传递路径长度取最短原则,传递路径长度相等时,采取最先申明原则。
7. 排除依赖
依赖包里有些包不稳定,可以排除该依赖包,如:
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.1</version> <exclusions> <exclusion> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1</version> </dependency>
8. 分类依赖
当同一个模块,所依赖的几个模块版本都相同时,可以使用maven里的属性做分类依赖,依赖版本升级时改一处即可。
<properties> <springframework.version>3.2.5</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> <type>pom</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${springframework.version}</version> <type>jar</type> <scope>compile</scope> </dependency> </dependencies>
9. 优化依赖
1) mvn dependency:list
查出依赖列表
2) mvn dependency:tree
查出依赖列表,按tree排列
3) mvn dependency:analyze
查找出在编译和测试中未使用但显示声明的依赖