首頁 > 軟體

解決SpringCloud下spring-boot-maven-plugin外掛的打包問題

2023-03-29 06:02:18

一、Maven生命週期、階段、目標         

 之前一直對Maven的3套生命週期有點不清楚,記錄下自己的理解。
        生命週期,就是一個事物從初始到消亡、開始到結束的過程,而Maven的生命週期就是指Maven官方對專案執行Maven構建從開始使用到使用結束整個流程的定義。
        而所說的Mavn有3套生命週期,就是指Maven從開始使用到使用結束要經過3個生命週期的流程,這3個生命週期各自獨立的,依次經過的生命週期分別是 clean、default、site,每個生命週期流程中也包含了不同的 phase(或者稱作階段),這些階段也是有先後順序的。可以說3套生命週期就是對這些階段做的一個邏輯上劃分、分類。

  • clean生命週期:因為專案如果是已經有部署過的話,我們肯定是要先把已經編譯生成好的檔案,要先清除掉。
  • default生命週期:然後執行一些測試、編譯等步驟,default才是我們的重點,也是包含了最多的階段。
  • site生命週期:最終釋出到伺服器上。        

        這樣最終就形成了3套生命週期。當然以上的生命週期、階段其實都是Maven官方自己所定義的一些邏輯上Maven專案應該經過的流程,並不一定每個專案都會經過這些所有的流程。而且使用者可以通過自定義外掛的方式,來將外掛繫結到各個階段,當我們在Maven執行命令的時候,就會執行自定義的特殊業務。
        比如對於spring-boot-maven-plugin,這個外掛,我們使用這個外掛的時候可以自定義該外掛的phase為pre-clean。

         mvn執行階段的命令格式是:mvn 階段1 [階段2] [階段n]。那麼當執行mvn pre-clean命令,就會執行pre-clean階段的流程,該流程在maven官方應該是沒有執行任務邏輯的。我們可以對比下對一個專案執行pre-clean和clean的差別:只有clean的時候才多了實執行的delete的操作。

        但是我們設定了這個<phase>pre-clean</phase>繫結後,我們執行pre-clean命令,自然就會執行到spring-boot-maven-plugin這個外掛的邏輯。這裡只是為了演示有繫結了pre-clean階段的動作,實際專案上是不應該繫結到pre-clean階段上的。

         並且在一個階段上也可以指定不同的goal/目標(可以稱之為這個外掛所提供的功能),一個外掛可以提供多種不同的goal/目標/功能,在IDEA的Maven控制面板上開啟該pom專案,可以看到這個spring-boot外掛就是包含了這些目標:build-info、help、repackage、run、start、stop。

        而我們上面設定了<goal>repackage</goal>,意味著在執行pre-clean階段的時候,會實際執行到該外掛的repackage這個目標。可以看到執行mvn pre-clean的結果,這個就是執行了repackage目標。在執行mvn命令可以指定要執行的目標,所以上面相當於執行了:mvn pre-clean:repackage

         在clean這個生命週期中,Maven總共定義了三個階段,分別是:pre-clean、clean、post-clean,各個階段有先後順序,執行某個階段的時候會有序執行其前面的所有階段。比如執行mvn post-clean,則依次執行pre-clean、clean、post-clean。可以看到當我們執行mvn post-clean的時候,也會出現了上面那樣pre-clean時的錯誤

         當我們在使用該外掛的時候,沒有定義phase的話,會自動使用其外掛定義的時候用的defaultPhase。比如我們使用的spring-boot-maven-plugin沒有設定phase,則預設的phase是外掛原始碼RepackageMojo在@Mojo定義的引數defaultPhase,也就是package階段了。所以我們只要增加了goal的設定,即使沒有設定pahse,也可以在package階段直接打包了

 二、SpringCloud下spring-boot-maven-plugin外掛的打包的問題

        在SpringCloud專案中的spring-boot-maven-plugin設定如下:

         當我們直接在SpringCloud專案下,對各個微服務子專案直接用命令mvn clean package打包會發現最終打出來的jar包並非可執行jar包,而只是我們專案原始檔的普通jar包。

         正確的打包命令應該是mvn clean package spring-boot:repackage,打包結果如下圖。其中.original結尾的檔案,就是專案原始碼最初的jar包,然後springboot打包外掛再根據該jar包再生成最終的可執行jar包。

三、SpringCloud正確的打包方式

        為什麼SpringCloud工程打可執行jar的命令是:mvn clean package spring-boot:repackage,而那些繼承了spring-boot-starter-parent的專案可以直接通過mvn clean package就可以打可執行jar包?

        這是因為在spring-boot-starter-parent的專案裡已經幫我們將打包外掛繫結到了repackage的目標,而該外掛如上文所提到的,已經預設繫結到了package的階段,所以當我們在SpringBoot專案執行mvn clean package的時候其實就自動執行了打普通jar包、並且通過repackage最終打成可執行jar包的流程。

         所以如果我們的SpringCloud想要也能夠像SpringBoot那樣執行打包命令的話,可以在SpringCloud的父pom工程也定義好plugin的repackage目標:

         這樣在子工程執行package後,就可以發現已經可以自動執行打普通jar包的目標了,接著繼續執行repackage目標,最終就是我們所要的可執行jar包。

         如果只是單獨執行mvn spring-boot:repackage,會報錯:Source file must be provided。需要先package 與 spring-boot:repackage 在同一條命令執行才正確,可能外掛內部是在通過本次命令執行中,根據package打出來的普通jar包的基礎上進行repackage的,不會去獲取倉庫中已有的普通jar包。

到此這篇關於SpringCloud下spring-boot-maven-plugin外掛的打包問題的文章就介紹到這了,更多相關spring-boot-maven-plugin外掛打包內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com