基于 IDEA 创建 Maven 多模块项目。

1. 创建父项目

父项目必须遵循以下两点要求:

  • packaging 标签的文本内容必须设置为 pom。
  • 删除 src 目录。

1.1. 新建项目

文件 -》 新建 -》 项目
maven指定模块构建 maven多模块构建_intellij idea
Maven -》 下一步
maven指定模块构建 maven多模块构建_intellij idea_02
填写名称,GroupId,ArtifactId
maven指定模块构建 maven多模块构建_其他_03
选择在新窗口打开项目
maven指定模块构建 maven多模块构建_apache_04

1.2. 修改项目

(1)在pom.xml添加<packaging>pom</packaging>,此时pom.xml内容如下所示:

<?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>

    <groupId>com.gtcom</groupId>
    <artifactId>gtcom-data</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--打包方式-->
    <packaging>pom</packaging>

    <properties>
    	<!--指定编译环境 JDK 版本-->
        <maven.compiler.source>11</maven.compiler.source>
        <!--指定运行环境JDK版本-->
        <maven.compiler.target>11</maven.compiler.target>
        <!--指定项目构建编码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

(2)删除 src 目录。删除 src 前项目结构:
maven指定模块构建 maven多模块构建_apache_05
删除 src 后项目结构:
maven指定模块构建 maven多模块构建_maven_06
【3】添加编译插件配置,项目中会统一使用 JDK 版本和编译级别,所以项目的编译级别必须统一,那么将编译插件添加到父工程,子模块会无条件去继承父工程的插件。此时pom.xml内容如下所示:

【这一步不需要,因为子模块有 SpringBoot 模块,也有普通 Maven 模块,使用的编译插件配置并不相同】

【还有就是 properties 中目前配置的三个就直接配置的是 Maven 编译插件的配置,不需要再在 build 中配置一次了】

Maven 官方说明:Setting the -source and -target of the Java Compiler

<?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>

    <groupId>com.gtcom</groupId>
    <artifactId>gtcom-data</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--打包方式-->
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.encoding>UTF-8</project.build.encoding>
    </properties>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <!--插件名称-->
                <artifactId>maven-compiler-plugin</artifactId>
                <!--插件版本-->
                <version>3.8.1</version>
                <!--插件配置信息-->
                <configuration>
                    <!--编译环境 JDK 版本-->
                    <source>${maven.compiler.source}</source>
                    <!--运行环境 JDK 版本-->
                    <target>${maven.compiler.target}</target>
                    <!--编码格式-->
                    <encoding>${project.build.encoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2. 创建子模块(普通 Java 模块)

文件 -》 新建 -》 新模块
maven指定模块构建 maven多模块构建_其他_07
Maven -》 下一步
maven指定模块构建 maven多模块构建_xml_08
选择父项为上面创建的父项目,填写名称,GroupId,ArtifactId
maven指定模块构建 maven多模块构建_xml_09
建好后的项目结构:
maven指定模块构建 maven多模块构建_其他_10
子模块 data-service 的pom.xml(这里给子模块也提供了版本version,不提供的话会直接继承父项目的version),这里添加了源码打包插件配置,因为该模块需要打包发布到 Maven 私服供别的项目引用:

<?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">
    <parent>
        <groupId>com.gtcom</groupId>
        <artifactId>gtcom-data</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>data-service</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    
	<build>
        <plugins>
            <!--源码打包插件配置-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    
</project>

此时父项目 gtcom-data 的pom.xml,可以发现父项目包含的模块 modules 中已经有了 data-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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gtcom</groupId>
    <artifactId>gtcom-data</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--父项目包含的所有模块名称-->
    <modules>
        <module>data-service</module>
    </modules>

    <!--打包方式-->
    <packaging>pom</packaging>

    <properties>
        <!--指定编译环境JDK版本-->
        <maven.compiler.source>11</maven.compiler.source>
        <!--指定运行环境JDK版本-->
        <maven.compiler.target>11</maven.compiler.target>
        <!--指定项目构建编码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

3. 创建子模块(SpringBoot 模块)

先在父项目的pom.xml中添加 SpringBoot 的依赖声明:

<!--依赖声明-->
<dependencyManagement>
    <dependencies>
        <!--SpringBoot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.5.3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
</dependencyManagement>

然后按照上面建普通 Java 子模块的方法创建一个 data-web 模块。修改pom.xml文件,添加 SpringBoot 依赖,此时 data-web 的pom.xml内容如下,我这里添加了 SpringBoot 编译打包插件和资源打包配置:

<?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">
    <parent>
        <artifactId>gtcom-data</artifactId>
        <groupId>com.gtcom</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>data-web</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <dependencies>
        <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>
		<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>
    
	<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <resources>
            <!-- src/main/java下的xml资源编译到classes下 -->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!-- src/main/resources下的资源编译到classes下 -->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>

此时父项目的pom.xml,可以发现父项目包含的模块中已经有了 data-web 模块了,这里我添加了依赖声明,子模块中需要的包的版本统一配置在这里,子模块的依赖就不需要配置版本号了:

<?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>

    <groupId>com.gtcom</groupId>
    <artifactId>gtcom-data</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--父工程包含的所有模块名称-->
    <modules>
        <module>data-service</module>
        <module>data-web</module>
    </modules>

    <!--打包方式-->
    <packaging>pom</packaging>

    <properties>
        <!--指定编译环境JDK版本-->
        <maven.compiler.source>11</maven.compiler.source>
        <!--指定运行环境JDK版本-->
        <maven.compiler.target>11</maven.compiler.target>
        <!--指定项目构建编码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!--依赖版本管理-->
        <spring.boot.version>2.5.3</spring.boot.version>
        <mybatis.version>2.2.0</mybatis.version>
        <fastjson.version>1.2.76</fastjson.version>
        <commons.lang3.version>3.11</commons.lang3.version>
    </properties>

    <!--依赖声明-->
    <dependencyManagement>
        <dependencies>
            <!--springboot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <!--fastjson-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!--commons-lang3-->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons.lang3.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

手动添加一个 SpringBoot 启动类和一个 application.properties 文件,此时的项目结构:
maven指定模块构建 maven多模块构建_intellij idea_11
到这里就可以通过启动类直接运行 data-web 模块了。

4. 插件配置解释

普通 Maven 项目上运行 package 时的日志,通过观察可以发现调用的插件依次为红框标注的插件。
maven指定模块构建 maven多模块构建_apache_12
Maven 项目打的 Jar 包结构,里面并不包含依赖的 Jar 包:
maven指定模块构建 maven多模块构建_xml_13
SpringBoot 项目上运行 package 时调用的插件日志为:
maven指定模块构建 maven多模块构建_apache_14
SpringBoot 项目打的 Jar 包的结构,内部包含了依赖的 Jar 包,可直接运行:
maven指定模块构建 maven多模块构建_xml_15
maven指定模块构建 maven多模块构建_xml_16
由上可见,SpringBoot 项目较普通 Maven 项目的特别之处在于,SpringBoot 提供的插件将生成的 Jar 包进行了重新打包;这也是 BOOT-INF 文件夹的来由;

【注意:单独的 SpringBoot 项目的打包插件并不需要配置 executions】

6. 打包插件配置示例

6.1. 全 SpringBoot 模块项目

父项目 task-output 的 pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
        </plugin>
    </plugins>
</build>

子模块 output-common 的 pom:

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

子模块 output-executor 的 pom:

<dependencies>
    <dependency>
        <groupId>com.gtcom</groupId>
        <artifactId>output-common</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

子模块 output-manager 的 pom:

<dependencies>
    <dependency>
        <groupId>com.gtcom</groupId>
        <artifactId>output-common</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

6.2. 非全 SpringBoot 模块项目

父项目 gtcom-data,pom 中不做打包插件配置。

子模块 data-search 的 pom:(非 SpringBoot 模块)

<build>
	<plugins>
	    <!--源码打包插件配置-->
	    <plugin>
	        <groupId>org.apache.maven.plugins</groupId>
	        <artifactId>maven-source-plugin</artifactId>
	        <version>3.2.1</version>
	        <configuration>
	            <attach>true</attach>
	        </configuration>
	        <executions>
	            <execution>
	                <phase>compile</phase>
	                <goals>
	                    <goal>jar</goal>
	                </goals>
	            </execution>
	        </executions>
	    </plugin>
	</plugins>
</build>

子模块 data-task 的 pom:

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

    <dependency>
        <groupId>com.gtcom</groupId>
        <artifactId>data-search</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

子模块 data-common 的 pom:

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

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
        </plugin>
    </plugins>
</build>      

子模块 data-web 的 pom:

<dependencies>
    <dependency>
        <groupId>com.gtcom</groupId>
        <artifactId>data-common</artifactId>
    </dependency>

    <dependency>
        <groupId>com.gtcom</groupId>
        <artifactId>data-search</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring.boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>