Maven配置覆蓋父插件配置

    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.結論

    在本文中,我們看到瞭如何覆蓋父插件配置。

    首先,我們探討了默認行為。然後,我們看到了父母如何定義合併策略以及孩子如何拒絕合併策略。最後,我們看到瞭如何將插件標記為不可繼承的,以避免所有子代都必須重寫它。