前言
本文主要记录了如何构建多模块的Maven项目及其构建过程,并从分布式服务的场景出发,针对一个服务的更新,如何重新构建单一服务相关的模块,而避免重复地构建整一个项目。
项目结构
树状结构目录:
demo
├─demo-admin
│ └─pom.xml
├─demo-api
│ └─pom.xml
├─demo-service
│ └─pom.xml
└─pom.xml
IDEA项目结构:
聚合及继承结构
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-admin和demo-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-api与demo-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.跳过testCompile和test阶段
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就是一个独立模块;
独立模块由于不依赖于其他模块,所以在构建的compile、package、install阶段可以直接构建。
依赖模块的构建
依赖模块是指依赖了其他模块,例如demo-api依赖了demo-service模块;
或者被其他模块依赖的,例如demo-service被demo-api依赖。
对于被依赖模块,如果它没有再依赖其他模块,那么也可以看作独立模块;
对于有依赖其他模块的,在compile、package、install阶段需要提供被依赖模块的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