Maven协调具体的解释:
artifactId=testng; version=5.8; classifer=jdk15,maven就会从中央仓库(http://search.maven.org/#browse)中寻找对应的构件供我们使用。
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>
以下详解一下各个坐标元素:
groupId不应该仅仅相应于项目隶属的组织或公司,原因是一个组织下会有非常多实际项目,假设groupId仅仅定义到组织级别,后面能够看到。artifactId仅仅能相应Maven项目。那么实际项目这个层将难以定义。
最后,groupId的表示方式与java包名的表示方式类似,通常与域名反向一一相应。
比方上例的artifactId是nexus-indexer,使用了实际项目名nexus作为前缀。这样做的优点是方便寻找实际构件。
实际上,Maven定义了一套完整的版本号规范,以及快照(SNAPSHOT)的概念。在后面的章节将具体讨论。
当不定义packaging时,Maven会是用默认值jar。
附属构件与主构件相应。如上例中的主构件是nexus-indexer-2.0.0.jar。该项目还会通过一些插件生成如nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar这样一些附属构件,其包括了Java文档和源码。这时候,javadoc和sources就是这两个附属构件的classifier。这样。附属构件也就拥有了自己唯一的坐标。注意:不能直接定义项目的classifier,由于附属构件不是项目直接默认生成的,而是由附加的插件帮助生成。
依赖的配置:
<project>
...
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<type>...</type>
<scope>...</scope>
<optional>...</optional>
<exclusions>
<exclusion>
...
</exclusion>
...
</exlusions>
</dependency>
...
</dependencies>
...
</project>
每一个依赖能够包括的元素有:
- groupId、artifactId和version:依赖的基本坐标,对于不论什么一个依赖来说,基本坐标是最重要的,Maven依据坐标才干找到须要的依赖。
- type:依赖的类型,相应于项目坐标定义的packaging。大部分情况下。该元素不必声明,其默认值为jar。
- scope:依赖的范围。请见后面小节
- optional:标记依赖是否可选,请见后面小节
- exclusions:用来排除传递性依赖,请见后面小节
Maven依赖范围:
假设没有指定,就会默认使用该依赖范围。该此依赖范围对于编译、測试、执行三种classpath都有效。典型的样例是spring-core,在编译、測试和执行的时候都须要使用该依赖。
该依赖范围仅仅对于測试classpath有效。在编译主代码或者执行项目的时将无法使用此类依赖。典型的样例就是JUnit。它仅仅有在编译測试代码及执行測试环境的时候才须要。
该范围依赖,对于执行和測试class-path有效,但在编译主代码时无效。典型的样例是JDBC驱动实现。项目主代码的编译仅仅须要JDK提供的JDBC接口,仅仅有在执行測试或者执行项目的时候才须要实现上述接口的详细的JDBC驱动。
systemPath元素能够引用环境变量。如:
传递性依赖:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifact>
<version>1.1.1</version>
</denpendency>
Maven会解析各个直接依赖的POM。将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目之中。
例如以下表所看到的,最左边一列表示第一直接依赖范围。最上面一行表示第二直接依赖范围。中间的交叉单元格则表示传递性依赖范围。
compile | test | provided | runtime | |
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | - | provided |
runtime | runtime | - | - | runtime |
依赖调解:
但有时候造成问题时。我们须要知道该传递性依赖是从哪条依赖路径引入的。
可选依赖:
然而。因为这里X、Y是可选依赖,依赖将不会得以传递。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc3</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc3</version>
</dependency>
</dependencies>
</project>
在上面的样例中,更好的做法是为MySql和PostgreSQL分别创建一个Maven项目。基于相同的groupId分配不同的artifactId,如com.juvenxu.mvnbook;project-b-mysql和com.juvenxu.mvnbook:project-b-postgresql,在各自的POM中声明相应的JDBC驱动依赖,并且不适用可选依赖,用户则依据须要选择使用project-b-mysql或者project-b-postgresql。因为传递性依赖的作用。就不再声明JDBC驱动依赖。
最佳实践:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-c</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-c</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
</project>
Frame-work,这些依赖的版本号会一起升级。
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>account-email</artifactId>
<name>Account Email</name>
<version>1.0.0-SNAPSHOT</version> <properties>
<springframework.version>2.5.6</springframework.version>
</properties> <dependencies>
<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>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>
也就是说。能够使用美元符号和大括弧围绕的方式引用Maven属性。然后,将全部Sping Framework依赖的版本号值用这一属性引用表示。
优化依赖:
使用该工具能够得出两类内容:
因此。一般应该显式声明不论什么项目中直接用到的依赖。
版权声明:本文博客原创文章。博客,未经同意,不得转载。