在进行分布式体系开发时,咱们一般会创立多个模块的工程项目。即每一个功能便是一个Spring Boot工程,作为一个个模块,然后这些模块都会有一个父模块,父模块一般没有代码只要一个pom.xml

今天就来分享一下Spring Boot怎么创立一个多模块项目,以创立一个两个子模块的工程为例。

1,创立父模块

在IDEA中,创立一个Spring Boot项目,可是不勾选任何依靠:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

Spring Boot多模块项目的创建和配置(Maven工程多模块)

创立好之后,将父模块中除了pom.xml文件之外的全部文件删去:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

由于父模块只是做一个模块和依靠办理的效果,因此不需求代码。

然后修正这个父模块的pom.xml文件,首先把<dependencies>节点、<build>节点和<properties>全部删去:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

然后修正版别号为自己定义的(便利后续子模块指定父模块):

Spring Boot多模块项目的创建和配置(Maven工程多模块)

然后修正父模块打包方式为pom,在其中参加如下语句即可:

<packaging>pom</packaging>

Spring Boot多模块项目的创建和配置(Maven工程多模块)

好的,到这儿父模块修正就完结了!

2,创立子模块并承继父模块

在左边项目树中父模块位置右键新建Spring Boot工程:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

Spring Boot多模块项目的创建和配置(Maven工程多模块)

Spring Boot多模块项目的创建和配置(Maven工程多模块)

然后把子模块不需求的文件也删掉(只留pom.xmlsrc文件夹):

Spring Boot多模块项目的创建和配置(Maven工程多模块)

修正该子模块的pom.xml文件,首先把子模块<parent>中的工件坐标改成和上述父模块共同:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

Spring Boot多模块项目的创建和配置(Maven工程多模块)

然后删去子模块的<groupId>节点,由于一般子模块承继父模块,子模块的组id是和父模块的共同的:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

ok,到此子模块创立并装备完结!此时这个子模块(工件名module-one)就承继了刚刚的父模块。

然后以这个步骤再创立一个子模块module-two

Spring Boot多模块项目的创建和配置(Maven工程多模块)

最终整个工程就创立完结了!总共两个子模块。

3,在父模块中指定子模块

回到父模块的pom.xml文件,添加<modules>节点,在其中参加<module>节点以指定子模块:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

需求留意的是,<module>节点中的内容是子模块工程的文件夹名!所以一般规范起见子模块工程的文件夹名一般和它的组件名共同。

Spring Boot多模块项目的创建和配置(Maven工程多模块)

然后在父模块文件夹中履行mvn clean package试试:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

能够看见构建打包成功,以及每个模块的构建时间。

到此,多模块项目就创立完结了!

4,子模块之间的互相引用

在多模块项目中,子模块的互相引用也很便利。

比如说上述module-one要调用module-two中的类,就直接把module-two的工件坐标参加到module-onepom.xml的依靠部分即可!

Spring Boot多模块项目的创建和配置(Maven工程多模块)

更新一下Maven工程,就能够在module-one中调用module-two的类了!

不过这个时候运行工程是没有任何问题的,可是打包会出错:尽管module-one依靠了module-two,可是依然会在打包module-one的时候,提示找不到module-two中的类。

Spring Boot多模块项目的创建和配置(Maven工程多模块)

这是由于Spring Boot打包的模式问题,咱们翻开被依靠模块module-twopom.xml文件找到最下面<build>节点中,在spring-boot-maven-plugin插件部分中参加下面装备:

<classifier>exec</classifier>

最终如下:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

这个时候对父模块打包,就成功了!

Spring Boot多模块项目的创建和配置(Maven工程多模块)

5,再看parentmodules标签

在上述无论是子模块承继父模块仍是父模块中声明子模块,主要便是用到了parent标签和modules标签。那么这儿有一个疑问了:已然子项目运用了parent指定父项目,那父项目中为什么还需运用modules指定子项目?这么做是否有些冗余?

事实上,这两个标签不仅仅是指定联系,还有着其它不同的效果。

(1) parent标签

parent标签便是用于声明该子模块的父模块了!也便是说,一个子模块要承继父模块,只需在parent中声明父模块的工件坐标即可。

当多个子模块承继了同一个父模块时:

  • 它们都会承继父模块中的依靠、插件、特点等等
  • 这些子模块之间也能够彼此引用

在上述比如中,咱们的子模块文件夹和父模块pom.xml在同一目录下,假如不在同一目录呢?那还需求在子模块的parent中运用relativePath来指定父模块的pom.xml的相对路径。

例如现在父项意图pom.xml文件不在子项意图上一级目录中,而是在子项意图上两级目录中,你能够将relativePath设置为../../pom.xml如下:

<parent>
	<groupId>com.gitee.swsk33</groupId>
	<artifactId>total-module</artifactId>
	<version>1.0.0</version>
	<!-- 指定父项目pom.xml位置 -->
	<relativePath>../../pom.xml</relativePath>
</parent>

留意,relativePath中指定的是相对路径,而且是父模块pom.xml相关于该子模块pom.xml文件的路径

(2) modules标签

当你现在需求构建父项目,比如在父项意图根目录下履行构建指令(如mvn clean install)时,一切承继了该父项意图子模块都会被构建吗?显然不是的。

只要声明在父项意图modules中的子模块,才会被构建。

想必现在咱们知道了两者的区别了,parent声明承继,主要是承继特点、依靠等等父项意图特点,而父项目中的modules是指定哪些子模块会随着该父模块一起被构建。

所以假如你的项目中有的用于测验的子项目需求承继父项目,可是又不期望这些用于测验的模块被构建,你就能够不在父项目中的modules中声明它们。

6,依靠办理

多模块项目中模块变多了,依靠办理不妥也会导致很多不可思议的问题。可是假如对每个模块别离办理依靠及其版别,会相当费事。

(1) 共用的依靠

假定上述module-onemodule-two都需求依靠fastjson2,咱们往常并不会依次在module-onemodule-two中别离独自参加其依靠,而是直接在父模块pom.xml中指定,和平时相同,在父模块的pom.xmldependencis节点中参加即可:

Spring Boot多模块项目的创建和配置(Maven工程多模块)

这样,子模块中即使是不参加fastjson2依靠,也能够运用这个库了!由于子模块除了能够运用自己的依靠之外,还会向上查找父模块的依靠,也便是说,父模块的依靠是向下承继的,因此关于一切模块都要运用的依靠,咱们能够写在父模块中。

所以,两个模块都依靠于Spring Web话,也能够将两个模块的Spring Web依靠移至父模块。

所以说父模块和子模块中,依靠也有着承继的联系!事实上,父模块的properties也是向下承继的。

(2) 依靠版别办理

假如现在module-one依靠于okhttps4.0.0版别,而module-two依靠于commons-io2.11.0版别,显然这时咱们不适合再在父模块中参加了,仍是各自参加对应依靠。

Spring Boot多模块项目的创建和配置(Maven工程多模块)

现在由于只要两个模块,这么做看起来很合理。可是假定现在又多了module-threemodule-four等等,它们也是别离依靠于okhttpscommons-io,那么咱们又要别离在这两个模块中别离独自参加依靠。

摸块 依靠
module-onemodule-three okhttps
module-twomodule-four commons-io

可能一开始没有问题,可是后边模块依靠版别需求更新,可是一个个地更新难免会有遗漏,导致部分模块尽管依靠相同可是版别不共同,最终整个体系也呈现了不可思议地错误,还难以排查。

就假定后边你把module-oneokhttps更新到了4.0.1版别,可是module-threeokhttps依然是4.0.0版别,这样整个体系就可能呈现问题乃至无法启动。

尤其是模块变成十几个乃至上百个了,一个个地手动修正是简直不可能的,要怎么让每个模块运用的依靠版别一致呢?

这时,咱们就要凭借dependencyManagement标签了!

dependencyManagement用于办理依靠的版别,咱们在父模块的pom.xml参加这个标签:

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>cn.zhxu</groupId>
         <artifactId>okhttps</artifactId>
         <version>4.0.0</version>
      </dependency>
      <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
         <version>2.11.0</version>
      </dependency>
   </dependencies>
</dependencyManagement>

然后,在子模块中,就能够把对应的依靠版别去掉了!

Spring Boot多模块项目的创建和配置(Maven工程多模块)

可见这儿,子模块中只需求引进对应依靠,而不需求指定版别了!由于子模块会向上查找父模块中dependencyManagement标签中对应依靠的版别

这样,就起到了一致办理版别的效果,只需求在父模块的dependencyManagement中修正对应依靠版别,子模块中对应依靠都会相应地运用这个版别。

dependencyManagement的留意事项:

  • dependencyManagement仅用于办理版别,而不会为自己以及子模块导入依靠,因此在dependencyManagement中声明依靠后,对应的子模块依然需求在dependencies中参加依靠
  • pom.xmldependencyManagementdependencies同级,而且dependencyManagement中也需求有一个dependencies
  • dependencyManagement不仅能够办理子模块的依靠版别,也能够办理本身的依靠版别
  • 若不想让某个子模块运用父模块dependencyManagement的版别,那就在这个子模块的dependencies中声明对应版别

(3) 总结

总而言之,关于一切子模块都共用的依靠,咱们只需在父模块的dependencies中引进这个依靠即可,而不需求再在子模块pom.xml中引进。

而关于不是一切子模块都需求的依靠,而是部分子模块需求的,又要一致版别办理,这时除了在需求这个依靠的子模块中引进依靠之外,还需求在父模块中的dependencyManagement声明这个依靠及其版别,这时,能够去掉子模块中对应依靠的版别号,使其遵循父模块中声明的版别。

示例仓库地址

  • 简略多模块项目
  • 一致依靠办理的多模块项目