Maven 引入插件可以在POM文件中进行配置,在build标签中,通过pluginManagement ,plugins ,plugin标签来引入插件
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-source-pluginartifactId>
<version>2.1version>
<configuration>
<attach>trueattach>
configuration>
<executions>
<execution>
<phase>compilephase>
<goals>
<goal>jargoal>
goals>
execution>
executions>
plugin>
plugins>
pluginManagement>
除了必要的groupId,artifactId,version三个坐标系元素外(下称坐标系元素),我们还可以通过配置块configuration 和 执行块executions对单个插件进行进一步的配置,由于每一个插件的配置和执行块的配置不尽相同,这里就不做过多讨论。
一个插件可能具有多个目标项,例如 我们学习的maven的内置插件中的compiler插件,
compiler插件有两个目标,分别是compile 和testCompile,分别表示编译源代码 和 编译测试代码,
command
插件标签中,我们通常 通过configuration配置块 及 executions来对插件进行进一步的配置,每个目标可能具有单独的配置,甚至可能将插件的目标完全绑定到不同的阶段,以期在不同的阶段执行配置中的插件目标。
例如上例 中的配置, maven就会在phase(阶段)为compile(编译)的时候将源码打成jar包。
我们在日常的开发中也许有注意到在有的pom文件中直接使用plugins包裹plugin进行插件的引入,而有的pom文件在plugins标签的外围还包裹pluginManagement 标签。那么两者之间有何区别呢?
简单来说:
pluginManagement 包裹的插件列表 仅表示 插件的声明和定义,Maven不会加载该插件;
而plugins直接包裹的插件列表 则真实的引入了插件。
pluginManagement一般是用来在父POM中定义和配置插件,提供给子POM使用,子POM则使用plugins包围的plugin标签定义该标签,如果你在父POM中定义了版本之后,子模块中可以仅定义groupId和artifactId两个元素,而不用指定版本。这样做的好处是统一管理插件。
示例:
父级pom
<build>
...
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-jar-pluginartifactId>
<version>2.6version>
<executions>
<execution>
<id>pre-process-classesid>
<phase>compilephase>
<goals>
<goal>jargoal>
goals>
<configuration>
<classifier>pre-processclassifier>
configuration>
execution>
executions>
plugin>
plugins>
pluginManagement>
...
build>
子级pom
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-jar-pluginartifactId>
plugin>
plugins>
...
build>
maven通过pom文件实现项目之间的继承和单向依赖。
我们通常可以使用dependencyManagement 、dependencys、dependency三个标签来引入依赖。
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>3.8.1version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.6version>
dependency>
dependencies>
dependency 依赖块中包含多个子元素,除坐标系元素之外,这里仅学习一些常用的元素。
maven在Maven2.0中引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚地知道该传递性依赖是从哪条依赖路径引入的。
maven对于依赖相同的资源,默认会做出以下优化:
例如,项目A有这样的依赖关系 : A–>B–>C–>X(1.0)、A–>D–>X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版 本的X,那么哪个X会被maven解析使用呢?两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。maven依赖调解的第一原则:路径最近者优先。该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
依赖调解第一原则不能解决所有问题,比如这样的依赖关系:A–>B–>Y(1.0),A–>C–>Y(2.0),Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。那么到底谁会被解析使用呢?在maven2.0.8及之前的版本中,这是不确定的,但是maven2.0.9开始,为了尽可能避免构建的不确定性,maven定义了依赖调解的第二原则:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用。顺序最靠前的那个依赖优胜。
这个区别于上文讲过的pluginManagement和plugins是非常相似的。