Maven坐标为各种构件引入了秩序,任何一个构件都必须明确定义自己的坐标,而一组Maven坐标是通过一些元素定义的,它们是:
groupId, artifactId, version, packaging, classifier
例如:
<groupId>org.sonatype.nexus</groupId> <artifaceID>nexus-indexer</artifactId> <version>2.0.0</version> <packaing>jar</packaing>
上述5个元素中,groupId,artifactId,version是必须定义的,packaging是可选的,默认为jar,而classfier是不能直接定义的。
项目构件的文件名是与坐标相对应的,一般的规划为artifactId-version[-classfier].packaing
一个依赖可以声明如下的一些元素:
<project> ... ... <dependencies> <dependency> <groupId>...</groupId> <artifaceId>...</artifactId> <version>...</version> <type>...</type> <scope>...</scope> <optional>...</optional> <exclusions> <exclusion> ... ... </exclusion> ... ... </exclusions> </dependency> ... ... </dependencies> ... ... </project>
groiupId,artifactId,version——依赖的基本坐标
依赖范围就是用来控制依赖与这三种classpath(编译classpath,测试classpath,运行classpath)的关系,Maven有一下几种依赖范围:
例如:
account-mail项目有一个spring-core的依赖,而实际上spring-core也有它自己的依赖,我们可以直接访问位于中央仓库的该构件的POM,该文件包含了一个comoom-logging依赖。commons-logging就会成为account-email的compile的一个传递性依赖。
有了传递性依赖,在使用Spring Framework的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖。Maven会解析各个直接依赖的POM,将那些必要的简介依赖,以传递性依赖的形式引入到当前的项目中。
在理想的情况下,是不应该使用可选依赖的。
传递性依赖会给系那个亩隐式地引入很多依赖。但是有些时候这种特性也会带来问题。
例如,当前项目有一个第三方依赖,而这个第三方依赖由于某些原因依赖了另一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,而SNAPSHOT的不稳定性会直接影响到当前的项目,这时就需要排除掉该SNAPSHOT,并在当前项目中声明该类库的某个正式发的版本。
代码中使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。声明exclusion的时候只需要groupId和artifactId,而不需要version。
比如对于使用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>
mvn dependency:list
mvn dependency:tree
mvn dependency:analyze