1.概述
在Maven多模块项目中,有效的POM是合并该模块及其父级中定义的所有配置的结果。
为了避免模块之间的冗余和重复,我们通常在共享父级中保留通用配置。但是,如果我们需要对子模块进行自定义配置而不影响其所有同级,则可能会遇到挑战。
在本教程中,我们将学习如何覆盖父插件配置。
2.默认配置继承
插件配置使我们可以在项目之间重用通用的构建逻辑。如果父级具有插件,则子级将自动拥有它,而无需其他配置。这就像继承。
为此,Maven在元素级别合并XML文件。如果子元素定义了一个具有不同值的元素,它将替换父元素中的元素。让我们来看看实际情况。
2.1。项目结构
首先,让我们定义一个多模块Maven项目进行试验。我们的项目将由一名父母和两名子女组成:
+ parent
+ child-a
+ child-b
假设我们要配置maven-compiler-plugin
以在模块之间使用不同的Java版本。让我们将项目配置为通常使用Java 11,但让其child-a
使用Java 8。
我们将从parent
配置开始:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<maxmem>512m</maxmem>
</configuration>
</plugin>
在这里,我们指定了另一个我们也要使用的maxmem
但是,我们希望child-a
具有自己的编译器设置。
因此,让我们将child-a
配置为使用Java 8:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
现在我们有了示例,让我们看看这对有效的POM有什么作用。
2.2。了解有效的POM
有效的POM受各种因素影响,例如继承,配置文件,外部设置等。为了查看实际的POM,让我们从child-a
目录mvn help:effective-pom
mvn help:effective-pom
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<maxmem>512m</maxmem>
</configuration>
</plugin>
不出所料, child-a
有其自身的source
值和target
但是,另一个惊喜是它还具有其父级maxmem
这意味着,如果定义了任何子级属性,它将获胜,否则将使用父级属性。
3.高级配置继承
当我们要微调合并策略时,可以使用属性。这些属性放在我们要控制的XML元素上。而且,它们将被继承,并且仅影响一级子级。
3.1。使用Lists
在前面的示例中,我们看到了如果子级拥有不同的值会发生什么。现在,我们将看到子级具有不同元素列表的情况。作为示例,让我们来看一下使用maven-resources-plugin包含多个资源目录。
作为基准,让我们将parent
配置为包括来自parent-resources
目录的资源:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>parent-resources</directory>
</resource>
</resources>
</configuration>
</plugin>
此时, child-a
将从其父级继承此插件配置。但是,假设我们要为child-a
定义一个备用资源目录:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
</configuration>
</plugin>
现在,让我们回顾一下有效的POM:
mvn help:effective-pom
...
<configuration>
<resources>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
</configuration>
在这种情况下,整个列表将被子配置覆盖。
3.2。附加父配置
也许我们希望某些子级使用公共资源目录并定义其他子级。为此,我们可以在父级的resources元素上**combine.children=”append”
**
<resources combine.children="append">
<resource>
<directory>parent-resources</directory>
</resource>
</resources>
因此,有效的POM将包含以下两者:
mvn help:effective-pom
....
<resources combine.children="append">
<resource>
<directory>parent-resources</directory>
</resource>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
combine
属性不会传播到任何嵌套元素。因此,如果resources
部分是一个复杂的结构,则嵌套元素将使用默认策略进行合并。
3.3。覆盖子配置
在前面的示例中,由于父组合策略,孩子并不能完全控制最终的POM。子级可以通过在其resources
元素**combine.self=”override”
**
<resources combine.self="override">
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
在这种情况下,子级重新获得控制权:
mvn help:effective-pom
...
<resources combine.self="override">
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
4.不可继承的插件
先前的属性适用于微调,但是当孩子完全不同意其父母时,它们不适用。
为了避免插件被完全继承,我们可以在父级添加属性<inherited>false</inherited>
:
<plugin>
<inherited>false</inherited>
<groupId>org.apache.maven.plugins</groupId>
...
</plugin>
这意味着该插件将仅应用于父级,而不会传播到其子级。
5.结论
在本文中,我们看到了如何覆盖父插件配置。
首先,我们探讨了默认行为。然后,我们看到了父母如何定义合并策略以及孩子如何拒绝合并策略。最后,我们看到了如何将插件标记为不可继承的,以避免所有子代都必须重写它。
0 评论