Maven多模块及单模块构建过程项目演示

430 阅读7分钟

前言

本文主要记录了如何构建多模块的Maven项目及其构建过程,并从分布式服务的场景出发,针对一个服务的更新,如何重新构建单一服务相关的模块,而避免重复地构建整一个项目。

项目结构

树状结构目录:

demo
 ├─demo-admin
 │	└─pom.xml
 ├─demo-api
 │	└─pom.xml
 ├─demo-service
 │	└─pom.xml
 └─pom.xml

IDEA项目结构: image.png

聚合及继承结构

demo/pom.xml

demo/pom.xml顶级POM文件作为聚合模块;
<packaging>需要指定为pom
<modules>中则指定了聚合的各个子模块。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
  
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
    </parent>

    <groupId>com.wei</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>demo-admin</module>
        <module>demo-api</module>
        <module>demo-service</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

demo/demo-admin/pom.xml

demo-admin及其他子模块均需要用<parent>指定聚合模块;
作为子模块,可以不用显示指定<groupId><version>,因为会从<parent>中继承。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wei</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>demo-admin</artifactId>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

demo/demo-service/pom.xml

demo-service子模块不作为一个可运行Java应用,所以没有用到spring-boot-maven-plugin
demo-service不同于demo-admindemo-api
demo-service模块将作为demo-api的一个依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>demo</artifactId>
        <groupId>com.wei</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>demo-service</artifactId>

</project>

demo/demo-api/pom.xml

demo-apidemo-admin同样作为子模块,但是额外依赖了demo-service模块。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.wei</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>demo-api</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.wei</groupId>
            <artifactId>demo-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

构建聚合模块

在聚合模块demo下执行构建:mvn clean install -Dmaven.test.skip=true
-Dmaven.test.skip=true用于跳过测试用例编译及测试。

生成反应堆(Reactor)

项目(子模块)的构建顺序并不按照聚合模块中定义的子模块顺序;
Maven会分析项目,解析子模块之间的依赖,重新排列构建顺序。

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] demo                                                               [pom]
[INFO] demo-admin                                                         [jar]
[INFO] demo-service                                                       [jar]
[INFO] demo-api                                                           [jar]

构建demo聚合模块

1.maven-clean-plugin:3.1.0执行clean目标(Goal
2.maven-install-plugin:2.5.2执行install目标

[INFO] ----------------------------< com.wei:demo >----------------------------
[INFO] Building demo 0.0.1-SNAPSHOT                                       [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo ---
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo ---
[INFO] Installing /Users/wei/IdeaProjects/demo/pom.xml to /Users/wei/.m2/repository/com/wei/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.pom

构建demo-admin模块

1.maven-clean-plugin:3.1.0执行clean
2.maven-compiler-plugin:3.8.1执行compile
3.跳过testCompiletest阶段
4.maven-jar-plugin:3.2.0执行jar(打包jar构件)
5.spring-boot-maven-plugin:2.6.2执行repackage
*spring-boot-maven-plugin会重新将jar构件需要的依赖jar包同时打包进去,代替原先打包好的jar构件;原先的jar构件以.original后缀重命名。
6.maven-install-plugin:2.5.2执行install

[INFO] -------------------------< com.wei:demo-admin >-------------------------
[INFO] Building demo-admin 0.0.1-SNAPSHOT                                 [2/4]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo-admin ---
[INFO] Deleting /Users/wei/IdeaProjects/demo/demo-admin/target
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ demo-admin ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo-admin ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/wei/IdeaProjects/demo/demo-admin/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ demo-admin ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo-admin ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo-admin ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ demo-admin ---
[INFO] Building jar: /Users/wei/IdeaProjects/demo/demo-admin/target/demo-admin-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.6.2:repackage (repackage) @ demo-admin ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo-admin ---
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-admin/target/demo-admin-0.0.1-SNAPSHOT.jar to /Users/wei/.m2/repository/com/wei/demo-admin/0.0.1-SNAPSHOT/demo-admin-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-admin/pom.xml to /Users/wei/.m2/repository/com/wei/demo-admin/0.0.1-SNAPSHOT/demo-admin-0.0.1-SNAPSHOT.pom

构建demo-service模块

构建过程可参考构建demo-admin模块

[INFO] ------------------------< com.wei:demo-service >------------------------
[INFO] Building demo-service 0.0.1-SNAPSHOT                               [3/4]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo-service ---
[INFO] Deleting /Users/wei/IdeaProjects/demo/demo-service/target
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ demo-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo-service ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/wei/IdeaProjects/demo/demo-service/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ demo-service ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo-service ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo-service ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ demo-service ---
[INFO] Building jar: /Users/wei/IdeaProjects/demo/demo-service/target/demo-service-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo-service ---
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-service/target/demo-service-0.0.1-SNAPSHOT.jar to /Users/wei/.m2/repository/com/wei/demo-service/0.0.1-SNAPSHOT/demo-service-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-service/pom.xml to /Users/wei/.m2/repository/com/wei/demo-service/0.0.1-SNAPSHOT/demo-service-0.0.1-SNAPSHOT.pom

构建demo-api模块

构建过程可参考构建demo-admin模块

[INFO] --------------------------< com.wei:demo-api >--------------------------
[INFO] Building demo-api 0.0.1-SNAPSHOT                                   [4/4]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo-api ---
[INFO] Deleting /Users/wei/IdeaProjects/demo/demo-api/target
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ demo-api ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo-api ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/wei/IdeaProjects/demo/demo-api/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ demo-api ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo-api ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo-api ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ demo-api ---
[INFO] Building jar: /Users/wei/IdeaProjects/demo/demo-api/target/demo-api-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.6.2:repackage (repackage) @ demo-api ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo-api ---
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-api/target/demo-api-0.0.1-SNAPSHOT.jar to /Users/wei/.m2/repository/com/wei/demo-api/0.0.1-SNAPSHOT/demo-api-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-api/pom.xml to /Users/wei/.m2/repository/com/wei/demo-api/0.0.1-SNAPSHOT/demo-api-0.0.1-SNAPSHOT.pom

构建单模块

在一个项目中并不总是需要重新构建整一个项目,而是仅仅构建某一个模块。尤其是在分布式服务中,当更新服务时,只需重新构建有变动的服务模块。

独立模块的构建

这里的独立模块是指没有依赖其他的模块,比如demo-admin就是一个独立模块;
独立模块由于不依赖于其他模块,所以在构建的compilepackageinstall阶段可以直接构建。

依赖模块的构建

依赖模块是指依赖了其他模块,例如demo-api依赖了demo-service模块;
或者被其他模块依赖的,例如demo-servicedemo-api依赖。
对于被依赖模块,如果它没有再依赖其他模块,那么也可以看作独立模块;
对于有依赖其他模块的,在compilepackageinstall阶段需要提供被依赖模块的jar构件;
通常这时候就需要先构建(install)被依赖模块,再构建依赖模块。

剪裁反应堆

依赖模块的构建方式通常要分步分别构建模块,而通过剪裁反应堆,可以只一次就将需要的模块一同构建。
以单独构建demo-api模块同时构建依赖的模块为例,观察剪裁反应堆的构建过程。
命令:mvn clean -pl demo-api -am install -Dmaven.test.skip=true

  • -pl, --projects:构建指定的模块,多个用英文逗号分割
  • -am, --also-make:同时构建指定模块的依赖模块
  • -amd, --also-make-dependents:同时构建依赖于指定模块的模块
  • -N, --None-recursive:不递归子模块
  • -rf, --resume-from:从指定的模块开始构建

1.生成反应堆

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] demo                                                               [pom]
[INFO] demo-service                                                       [jar]
[INFO] demo-api                                                           [jar]

2.构建demo聚合模块

[INFO] ----------------------------< com.wei:demo >----------------------------
[INFO] Building demo 0.0.1-SNAPSHOT                                       [1/3]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo ---
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo ---
[INFO] Installing /Users/wei/IdeaProjects/demo/pom.xml to /Users/wei/.m2/repository/com/wei/demo/0.0.1-SNAPSHOT/demo-0.0.1-SNAPSHOT.pom

3.构建demo-service模块

[INFO] ------------------------< com.wei:demo-service >------------------------
[INFO] Building demo-service 0.0.1-SNAPSHOT                               [2/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo-service ---
[INFO] Deleting /Users/wei/IdeaProjects/demo/demo-service/target
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ demo-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo-service ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/wei/IdeaProjects/demo/demo-service/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ demo-service ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo-service ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo-service ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ demo-service ---
[INFO] Building jar: /Users/wei/IdeaProjects/demo/demo-service/target/demo-service-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo-service ---
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-service/target/demo-service-0.0.1-SNAPSHOT.jar to /Users/wei/.m2/repository/com/wei/demo-service/0.0.1-SNAPSHOT/demo-service-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-service/pom.xml to /Users/wei/.m2/repository/com/wei/demo-service/0.0.1-SNAPSHOT/demo-service-0.0.1-SNAPSHOT.pom

4.构建demo-api模块

[INFO] --------------------------< com.wei:demo-api >--------------------------
[INFO] Building demo-api 0.0.1-SNAPSHOT                                   [3/3]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ demo-api ---
[INFO] Deleting /Users/wei/IdeaProjects/demo/demo-api/target
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ demo-api ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 1 resource
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo-api ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/wei/IdeaProjects/demo/demo-api/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ demo-api ---
[INFO] Not copying test resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ demo-api ---
[INFO] Not compiling test sources
[INFO] 
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ demo-api ---
[INFO] Tests are skipped.
[INFO] 
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ demo-api ---
[INFO] Building jar: /Users/wei/IdeaProjects/demo/demo-api/target/demo-api-0.0.1-SNAPSHOT.jar
[INFO] 
[INFO] --- spring-boot-maven-plugin:2.6.2:repackage (repackage) @ demo-api ---
[INFO] Replacing main artifact with repackaged archive
[INFO] 
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ demo-api ---
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-api/target/demo-api-0.0.1-SNAPSHOT.jar to /Users/wei/.m2/repository/com/wei/demo-api/0.0.1-SNAPSHOT/demo-api-0.0.1-SNAPSHOT.jar
[INFO] Installing /Users/wei/IdeaProjects/demo/demo-api/pom.xml to /Users/wei/.m2/repository/com/wei/demo-api/0.0.1-SNAPSHOT/demo-api-0.0.1-SNAPSHOT.pom