在進(jìn)行分布式系統(tǒng)開發(fā)時(shí),我們通常會(huì)創(chuàng)建多個(gè)模塊的工程項(xiàng)目。即每一個(gè)功能就是一個(gè)Spring Boot工程,作為一個(gè)個(gè)模塊,然后這些模塊都會(huì)有一個(gè)父模塊,父模塊通常沒有代碼只有一個(gè)pom.xml
。
今天就來分享一下Spring Boot如何創(chuàng)建一個(gè)多模塊項(xiàng)目,以創(chuàng)建一個(gè)兩個(gè)子模塊的工程為例。
1,創(chuàng)建父模塊
在IDEA中,創(chuàng)建一個(gè)Spring Boot項(xiàng)目,但是不勾選任何依賴:
創(chuàng)建好之后,將父模塊中除了pom.xml
文件之外的全部文件刪除:
因?yàn)楦改K只是做一個(gè)模塊和依賴管理的作用,因此不需要代碼。
然后修改這個(gè)父模塊的pom.xml
文件,首先把<dependencies>
節(jié)點(diǎn)、<build>
節(jié)點(diǎn)和<properties>
全部刪除:
然后修改版本號(hào)為自己定義的(方便后續(xù)子模塊指定父模塊):
然后修改父模塊打包方式為pom,在其中加入如下語句即可:
xml復(fù)制代碼<packaging>pom</packaging>
好的,到這里父模塊修改就完成了!
2,創(chuàng)建子模塊并繼承父模塊
在左邊項(xiàng)目樹中父模塊位置右鍵新建Spring Boot工程:
然后把子模塊不需要的文件也刪掉(只留pom.xml
和src
文件夾):
修改該子模塊的pom.xml
文件,首先把子模塊<parent>
中的工件坐標(biāo)改成和上述父模塊一致:
然后刪除子模塊的<groupId>
節(jié)點(diǎn),因?yàn)橥ǔW幽K繼承父模塊,子模塊的組id是和父模塊的一致的:
ok,到此子模塊創(chuàng)建并配置完成!此時(shí)這個(gè)子模塊(工件名module-one
)就繼承了剛剛的父模塊。
然后以這個(gè)步驟再創(chuàng)建一個(gè)子模塊module-two
:
最后整個(gè)工程就創(chuàng)建完成了!總共兩個(gè)子模塊。
3,在父模塊中指定子模塊
回到父模塊的pom.xml
文件,添加<modules>
節(jié)點(diǎn),在其中加入<module>
節(jié)點(diǎn)以指定子模塊:
需要注意的是,<module>
節(jié)點(diǎn)中的內(nèi)容是子模塊工程的文件夾名!所以通常規(guī)范起見子模塊工程的文件夾名通常和它的組件名一致。
然后在父模塊文件夾中執(zhí)行mvn clean package
試試:
可以看見構(gòu)建打包成功,以及每個(gè)模塊的構(gòu)建時(shí)間。
到此,多模塊項(xiàng)目就創(chuàng)建完成了!
4,子模塊之間的互相引用
在多模塊項(xiàng)目中,子模塊的互相引用也很方便。
比如說上述module-one
要調(diào)用module-two
中的類,就直接把module-two
的工件坐標(biāo)加入到module-one
的pom.xml
的依賴部分即可!
更新一下Maven工程,就可以在module-one
中調(diào)用module-two
的類了!
不過這個(gè)時(shí)候運(yùn)行工程是沒有任何問題的,但是打包會(huì)出錯(cuò):雖然module-one
依賴了module-two
,但是仍然會(huì)在打包module-one
的時(shí)候,提示找不到module-two
中的類。
這是由于Spring Boot打包的模式問題,我們打開被依賴模塊module-two的pom.xml文件找到最下面<build>節(jié)點(diǎn)中,在spring-boot-maven-plugin插件部分中加入下面配置:
xml復(fù)制代碼<classifier>exec</classifier>
最終如下:
這個(gè)時(shí)候?qū)Ω改K打包,就成功了!
5,再看parent和modules標(biāo)簽
在上述無論是子模塊繼承父模塊還是父模塊中聲明子模塊,主要就是用到了parent
標(biāo)簽和modules
標(biāo)簽。那么這里有一個(gè)疑問了:既然子項(xiàng)目使用了parent
指定父項(xiàng)目,那父項(xiàng)目中為什么還需使用modules
指定子項(xiàng)目?這么做是否有些冗余?
事實(shí)上,這兩個(gè)標(biāo)簽不僅僅是指定關(guān)系,還有著其它不同的作用。
(1) parent標(biāo)簽
parent
標(biāo)簽就是用于聲明該子模塊的父模塊了!也就是說,一個(gè)子模塊要繼承父模塊,只需在parent
中聲明父模塊的工件坐標(biāo)即可。
當(dāng)多個(gè)子模塊繼承了同一個(gè)父模塊時(shí):
- 它們都會(huì)繼承父模塊中的依賴、插件、屬性等等
- 這些子模塊之間也可以相互引用
在上述例子中,我們的子模塊文件夾和父模塊pom.xml
在同一目錄下,如果不在同一目錄呢?那還需要在子模塊的parent
中使用relativePath
來指定父模塊的pom.xml
的相對(duì)路徑。
例如現(xiàn)在父項(xiàng)目的pom.xml文件不在子項(xiàng)目的上一級(jí)目錄中,而是在子項(xiàng)目的上兩級(jí)目錄中,你可以將relativePath設(shè)置為../../pom.xml如下:
xml復(fù)制代碼<parent>
<groupId>com.gitee.swsk33</groupId>
<artifactId>total-module</artifactId>
<version>1.0.0</version>
<!-- 指定父項(xiàng)目pom.xml位置 -->
<relativePath>../../pom.xml</relativePath>
</parent>
注意,relativePath
中指定的是相對(duì)路徑,并且是父模塊pom.xml
相對(duì)于該子模塊pom.xml
文件的路徑。
(2) modules標(biāo)簽
當(dāng)你現(xiàn)在需要構(gòu)建父項(xiàng)目,比如在父項(xiàng)目的根目錄下執(zhí)行構(gòu)建命令(如mvn clean install
)時(shí),所有繼承了該父項(xiàng)目的子模塊都會(huì)被構(gòu)建嗎?顯然不是的。
只有聲明在父項(xiàng)目的modules
中的子模塊,才會(huì)被構(gòu)建。
想必現(xiàn)在大家知道了兩者的區(qū)別了,parent
聲明繼承,主要是繼承屬性、依賴等等父項(xiàng)目的屬性,而父項(xiàng)目中的modules
是指定哪些子模塊會(huì)隨著該父模塊一起被構(gòu)建。
所以如果你的項(xiàng)目中有的用于測試的子項(xiàng)目需要繼承父項(xiàng)目,但是又不希望這些用于測試的模塊被構(gòu)建,你就可以不在父項(xiàng)目中的modules
中聲明它們。
6,依賴管理
多模塊項(xiàng)目中模塊變多了,依賴管理不當(dāng)也會(huì)導(dǎo)致很多莫名其妙的問題。但是如果對(duì)每個(gè)模塊分別管理依賴及其版本,會(huì)相當(dāng)麻煩。
(1) 共用的依賴
假設(shè)上述module-one
和module-two
都需要依賴fastjson2
,我們平常并不會(huì)依次在module-one
和module-two
中分別單獨(dú)加入其依賴,而是直接在父模塊pom.xml
中指定,和平時(shí)一樣,在父模塊的pom.xml
的dependencis
節(jié)點(diǎn)中加入即可:
這樣,子模塊中即使是不加入fastjson2
依賴,也可以使用這個(gè)庫了!因?yàn)樽幽K除了可以使用自己的依賴之外,還會(huì)向上查找父模塊的依賴,也就是說,父模塊的依賴是向下繼承的,因此對(duì)于所有模塊都要使用的依賴,我們可以寫在父模塊中。
所以,兩個(gè)模塊都依賴于
Spring Web
話,也可以將兩個(gè)模塊的Spring Web
依賴移至父模塊。
所以說父模塊和子模塊中,依賴也有著繼承的關(guān)系!事實(shí)上,父模塊的properties
也是向下繼承的。
(2) 依賴版本管理
假如現(xiàn)在module-one
依賴于okhttps
的4.0.0
版本,而module-two
依賴于commons-io
的2.11.0
版本,顯然這時(shí)我們不適合再在父模塊中加入了,還是各自加入對(duì)應(yīng)依賴。
目前因?yàn)橹挥袃蓚€(gè)模塊,這么做看起來很合理。但是假設(shè)現(xiàn)在又多了module-three
,module-four
等等,它們也是分別依賴于okhttps
與commons-io
,那么我們又要分別在這兩個(gè)模塊中分別單獨(dú)加入依賴。
摸塊 | 依賴 |
---|---|
module-one 和module-three
|
okhttps |
module-two 和module-four
|
commons-io |
可能一開始沒有問題,但是后面模塊依賴版本需要更新,但是一個(gè)個(gè)地更新難免會(huì)有疏漏,導(dǎo)致部分模塊雖然依賴一樣但是版本不一致,最后整個(gè)系統(tǒng)也出現(xiàn)了莫名其妙地錯(cuò)誤,還難以排查。
就假設(shè)后面你把module-one
的okhttps
更新到了4.0.1
版本,但是module-three
的okhttps
仍然是4.0.0
版本,這樣整個(gè)系統(tǒng)就可能出現(xiàn)問題甚至無法啟動(dòng)。
尤其是模塊變成十幾個(gè)甚至上百個(gè)了,一個(gè)個(gè)地手動(dòng)修改是幾乎不可能的,要如何讓每個(gè)模塊使用的依賴版本統(tǒng)一呢?
這時(shí),我們就要借助dependencyManagement
標(biāo)簽了!
dependencyManagement用于管理依賴的版本,我們?cè)诟改K的pom.xml加入這個(gè)標(biāo)簽:
xml復(fù)制代碼<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>
然后,在子模塊中,就可以把對(duì)應(yīng)的依賴版本去掉了!
可見這里,子模塊中只需要引入對(duì)應(yīng)依賴,而不需要指定版本了!因?yàn)?strong>子模塊會(huì)向上查找父模塊中dependencyManagement
標(biāo)簽中對(duì)應(yīng)依賴的版本。
這樣,就起到了統(tǒng)一管理版本的作用,只需要在父模塊的dependencyManagement
中修改對(duì)應(yīng)依賴版本,子模塊中對(duì)應(yīng)依賴都會(huì)相應(yīng)地使用這個(gè)版本。
dependencyManagement
的注意事項(xiàng):
-
dependencyManagement
僅用于管理版本,而不會(huì)為自己以及子模塊導(dǎo)入依賴,因此在dependencyManagement
中聲明依賴后,對(duì)應(yīng)的子模塊仍然需要在dependencies
中加入依賴 - 在
pom.xml
中dependencyManagement
和dependencies
同級(jí),并且dependencyManagement
中也需要有一個(gè)dependencies
-
dependencyManagement
不僅可以管理子模塊的依賴版本,也可以管理自身的依賴版本 - 若不想讓某個(gè)子模塊使用父模塊
dependencyManagement
的版本,那就在這個(gè)子模塊的dependencies
中聲明對(duì)應(yīng)版本
(3) 總結(jié)
總而言之,對(duì)于所有子模塊都共用的依賴,我們只需在父模塊的dependencies
中引入這個(gè)依賴即可,而不需要再在子模塊pom.xml
中引入。
而對(duì)于不是所有子模塊都需要的依賴,而是部分子模塊需要的,又要統(tǒng)一版本管理,這時(shí)除了在需要這個(gè)依賴的子模塊中引入依賴之外,還需要在父模塊中的dependencyManagement
聲明這個(gè)依賴及其版本,這時(shí),可以去掉子模塊中對(duì)應(yīng)依賴的版本號(hào),使其遵循父模塊中聲明的版本。文章來源:http://www.zghlxwxcb.cn/news/detail-655279.html
示例倉庫地址:文章來源地址http://www.zghlxwxcb.cn/news/detail-655279.html
- 簡單多模塊項(xiàng)目
- 統(tǒng)一依賴管理的多模塊項(xiàng)目
到了這里,關(guān)于Spring Boot多模塊項(xiàng)目的創(chuàng)建和配置(Maven工程多模塊)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!