坐标
Maven坐标为各种构件引入了秩序,任何一个构件都必须明确定义自己的坐标,而一组Maven坐标是通过一些元素定义的,它们是:
groupId, artifactId, version, packaging, classifier
例如:
<groupId>org.sonatype.nexus</groupId>
<artifaceID>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaing>jar</packaing>
- groupId——定义当前Maven项目隶属的实际项目
- artifactId——该元素定义实际项目中的一个Maven项目/模块,推荐的做法是使用实际项目名称作为artifactId的前缀。
- version——该元素定义Maven项目当前的版本
- packaging——该元素定义Maven项目的打包方式,打包方式通常与所生成构件的文件扩展名相对应,当不定义packaging的时候,Maven会使用默认值jar
- classfier——该元素用来帮助定义构建输出一些附属构件。
上述5个元素中,groupId,artifactId,version是必须定义的,packaging是可选的,默认为jar,而classfier是不能直接定义的。
项目构件的文件名
项目构件的文件名是与坐标相对应的,一般的规划为artifactId-version[-classfier].packaing
依赖——Dependencies
一个依赖可以声明如下的一些元素:
<project>
... ...
<dependencies>
<dependency>
<groupId>...</groupId>
<artifaceId>...</artifactId>
<version>...</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
... ...
</exclusion>
... ...
</exclusions>
</dependency>
... ...
</dependencies>
... ...
</project>
根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个项目依赖,每个依赖可以包含的元素有:
groiupId,artifactId,version——依赖的基本坐标
- type——依赖的类型,对应于项目坐标定义的packaging,大部分情况下,该元素不必声明,其默认值为jar
- scope——依赖的范围
- optional——标记依赖是否可选
- exclusion——用来排除传递性依赖
依赖范围——scope
依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行classpath)的关系,Maven有一下几种依赖范围:
- compile——编译依赖范围。如果没有指定,默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译,测试,运行三种classpath都有效。如spring-core
- test——测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。如JUnit
- provided——已提供依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在运行时无效。如servlet-api,运行时容器已经提供
- runtime——运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。如JDBC驱动实现
- system——系统依赖范围。
传递性依赖
例如:
account-mail项目有一个spring-core的依赖,而实际上spring-core也有它自己的依赖,我们可以直接访问位于中央仓库的该构件的POM,该文件包含了一个comoom-logging依赖。commons-logging就会成为account-email的compile的一个传递性依赖。
有了传递性依赖,在使用Spring Framework的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖。Maven会解析各个直接依赖的POM,将那些必要的简介依赖,以传递性依赖的形式引入到当前的项目中。
可选依赖——optional
在理想的情况下,是不应该使用可选依赖的。
排除依赖——exclusion
传递性依赖会给系那个亩隐式地引入很多依赖。但是有些时候这种特性也会带来问题。
例如,当前项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性会直接影响到当前的项目,这时就需要排除掉该SNAPSHOT,并在当前项目中声明该类库的某个正式发的版本。
代码中使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。声明exclusion的时候只需要groupId和artifactId,而不需要version。
归类依赖——Maven属性
比如对于使用Spring Framework来说,应该在一个唯一的地方定义版本,并且在dependency声明中应用这一版本,这样,在升级Spring Framework的时候就只需要修改一次。
<project>
<moduleVersion》4.0.0</moduleVersion>
<groupId>com.juven,mvnbook,account<.groupId>
<artifactId>account-email</artifactId>
<name>Account Email</name>
<properties>
<springframework.version>2.5.6</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifaceId>spring-core</artifactId>
<version>$(springframework.version)</version>
</dependency>
... ...
</dependencies>
... ...
</project>
这里用到了Maven属性,首先受用properties元素定义Maven属性。
优化依赖
mvn dependency:list
mvn dependency:tree
mvn dependency:analyze