Maven提供了dependencyManagement元素帮忙管理依赖,类似地,Maven也提供了pluginManagement元素帮忙管理插件。该元素中配置的依赖不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中配置的插件匹配时,pluginManagement的配置才会影响实际的插件行为。
前面有如何通过组件去将jar-no-fork目标绑定到verity生命周期阶段,以生成项目源码包。如果一个项目中有很多子模块,并且需要这些模块的源码包,那么很显然,为所有模块重复类似的插件配置不是最好的办法,这时最好的办法是在父POM中使用pluginManagement配置插件,代码如下:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
当子模块需要生成源码包的时候,只需要如下简单的配置,代码如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
子模块声明使用了maven-source-plugin插件,同时又继承了父模块的pluginManagement配置,两者基于groupId和artifactId匹配合并。有了pluginManagement元素,accout-email和accout-persist的POM也能得以简化了他们都配置了maven-compiler-plugin和maven-resources-plugin。可以将这两个插件的配置移到account-parent的pluginManagement元素中,代码如下:
<build>
<pluginMangement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifact>maven-resources-plugin</artifact>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginMangement>
</build>
accout-email和account-persist可以完全地移除关于maven-compiler-plugin和maven-resources-plugin的配置,但他们仍然能享受这这个插件的服务,前一插件开启了jdk1.5编译的支持,后一插件也会使用UTF-8编码处理资源文件。这背后涉及了很多Maven机制,首先,内置的插件绑定关系将两个插件绑定到了account-email和account-persist生命周期上,其次,超级POM为这两个插件申明了版本;最后,account-parent中的pluginManagement对这两个插件的行为进行了配置。
当项目中的多个模块有同样的插件配置时,应当将配置移到父POM的pluginMangement元素中。即使各个模块对于同一插件的具体配置不尽相同,也应当使用父POM的pluginManagement元素同意声明插件的版本。甚至可以要求将所有用到的插件的版本在父POM的pluginManagement中声明,子模块使用插件时不配置版本信息,这么做可以统一项目的插件版本,避免潜在的插件不一致或者不稳定的问题,也更易于维护