首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Maven 聚合與繼承實戰:多模組專案構建治理最佳實踐

     編輯:Java 綜合教學

Maven 聚合與繼承實戰:多模組專案構建治理最佳實踐

企業級專案往往包含十數個模組 (common、system、log、reports、monitor...)。Maven 聚合 解決「一鍵構建所有模組」,繼承 解決「消除重複配置」。二者結合,構建出清晰、可維護的多模組工程。

一、Maven 聚合 : 一鍵構建全專案

聚合 POM (UidpWeb/pom.xml)

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.uidp</groupId>
  <artifactId>UidpWeb</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging> <!-- 關鍵:聚合模組打包類型必須為 pom -->
  <name>UidpWeb</name>

  <modules>
    <module>parent</module> <!-- 父 POM 模組 -->
    <module>ThirdParty</module>
    <module>common</module>
    <module>log/pom-pack.xml</module> <!-- 指定子模組 POM 路徑 -->
    <module>biz/pom-pack.xml</module>
    <module>customer/pom-pack.xml</module>
    <module>strategy/pom-pack.xml</module>
    <module>reports/pom-pack.xml</module>
    <module>monitor/pom-pack.xml</module>
    <module>sysmgr/pom-pack.xml</module>
    <module>pom-app.xml</module> <!-- 統一打 WAR 包 -->
  </modules>
</project>

關鍵點

  • <packaging>pom</packaging>:聚合模組無源碼,僅作為構建入口
  • <modules>:聲明參與聚合的子模組相對路徑
  • 目錄結構:聚合 POM 通常置於專案根目錄,子模組為其子目錄
  • 平行目錄時使用 <module>../parent</module> 相對路徑

構建行為

執行 mvn clean install 於聚合 POM 目錄,Maven 會:

  1. 讀取所有 <module>
  2. 計算反應堆構建順序 (根據依賴關係拓撲排序)
  3. 按序構建每個模組

二、Maven 繼承 : 消除配置重複

父 POM (parent/pom.xml) - 模板角色

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.uidp</groupId>
  <artifactId>UidpParent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties> <!-- 統一版本管理 -->
    <springframework.version>3.2.8.RELEASE</springframework.version>
    <mybatis.version>3.2.2</mybatis.version>
    <junit.version>4.11</junit.version>
    <maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 更多屬性... -->
  </properties>

  <dependencyManagement> <!-- 依賴版本鎖定,子模組引用時可省略版本 -->
    <dependencies>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${springframework.version}</version>
      </dependency>
      <!-- 所有 Spring、MyBatis、Logging、Jackson、Servlet 等依賴... -->
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
      <!-- 更多插件管理... -->
    </plugins>
  </build>

  <distributionManagement> <!-- 統一發布配置 -->
    <repository>...</repository>
    <snapshotRepository>...</snapshotRepository>
  </distributionManagement>
</project>

子模組繼承父 POM (log/pom-pack.xml)

<project ...>
  <parent>
    <groupId>com.uidp</groupId>
    <artifactId>UidpParent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../parent/pom.xml</relativePath> <!-- 關鍵:指定父 POM 相對路徑 -->
  </parent>

  <artifactId>log</artifactId> <!-- 子模組必須聲明自己的 artifactId -->
  <packaging>war</packaging>

  <dependencies>
    <!-- 從 dependencyManagement 引用,無需版本號 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
    </dependency>
    <!-- 更多依賴... -->
    
    <!-- 模組專屬依賴 (不在父 POM 中) -->
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>1.8.6</version>
    </dependency>
  </dependencies>
  
  <build>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>7.2.2.v20101205</version>
        <configuration>...</configuration>
      </plugin>
    </plugins>
  </build>
</project>

三、核心機制深度解析

1. DependencyManagement vs Dependencies

特性dependencyManagementdependencies
作用聲明依賴坐標與版本 (模板)實際引入依賴到構建路徑
傳遞性不直接引入,子模組需聲明才生效直接引入,傳遞依賴自動帶入
版本鎖定統一版本,避免衝突若未聲明版本,向上查找 Management
典型用法父 POM 定義版本庫子模組按需引用

2. 可繼承的 POM 元素完整清單

  • 坐標相關:groupId, version (子模組可覆寫)
  • 專案信息:description, organization, inceptionYear, url, developers, contributors
  • 構建配置:build (源碼目錄、輸出目錄、插件、插件管理), reporting
  • 依賴管理:dependencies, dependencyManagement
  • 倉庫/分發:repositories, pluginRepositories, distributionManagement
  • 流程管理:issueManagement, ciManagement, scm, mailingLists
  • 自定義屬性:properties

3. relativePath 陷阱與最佳實踐

預設 relativePath=../pom.xml (父目錄)。若父 POM 不在父目錄,**必須顯式指定**:

<parent>
  <relativePath>../parent/pom.xml</relativePath>
</parent>

否則本地倉庫無父 POM 時構建失敗。

四、聚合與繼承的關係

  • 聚合:「整體管理部分」—— 父 POM 聚合子模組,關注構建順序與生命週期
  • 繼承:「部分共享整體」—— 子模組繼承父 POM,關注配置復用與版本統一
  • 實踐中常合二為一:根 POM 同時扮演聚合器與父 POM (如本例 UidpWeb 聚合 parent,parent 再被各業務模組繼承)

五、避坑指南

  1. 父 POM packaging 必須為 pom
  2. 子模組 artifactId 必須顯式聲明,避免坐標衝突
  3. dependencyManagement 中統一版本,子模組引用省略版本
  4. 插件管理同理使用 pluginManagement
  5. 多層繼承不超過 3 層,避免配置追溯困難
  6. 定期 mvn dependency:analyze 檢測未使用/未聲明依賴

掌握聚合與繼承,是從「會用 Maven」進階到「治理 Maven 多模組工程」的分水嶺。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved