打包可執行檔案
該外掛可以建立包含應用程式所有依賴項的可執行檔案(jar 檔案和 war 檔案),然後可以使用 java -jar
命令執行。
打包可執行檔案由 repackage
目標執行,示例如下所示
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
repackage 目標不適合單獨在命令列中使用,因為它作用於由 package 階段生成的源 jar (或 war )。要在命令列上使用此目標,您必須包含 package 階段:mvn package spring-boot:repackage 。 |
如果您正在使用 spring-boot-starter-parent ,則此類執行已透過 repackage 執行 ID 進行預配置,因此只需新增外掛定義即可。 |
上述示例會重新打包在 Maven 生命週期 package
階段構建的 jar
或 war
檔案,包括專案中定義的任何 provided
依賴。如果需要排除某些依賴項,可以使用 exclude
選項之一;更多詳情請參閱依賴排除。
預設情況下,原始(即不可執行的)artifact 會被重新命名為 .original
,但也可以使用自定義分類器保留原始 artifact。
目前不支援 maven-war-plugin 的 outputFileNameMapping 特性。 |
spring-boot-devtools
和 spring-boot-docker-compose
模組預設會自動排除(您可以使用 excludeDevtools
和 excludeDockerCompose
屬性控制)。為了使其在 war
打包中生效,必須將 spring-boot-devtools
和 spring-boot-docker-compose
依賴項設定為 optional
或使用 provided
範圍。
該外掛會重寫您的 manifest 檔案,特別是管理 Main-Class
和 Start-Class
條目。如果預設值不適用,您必須在 Spring Boot 外掛中配置這些值,而不是在 jar 外掛中。manifest 檔案中的 Main-Class
由 Spring Boot 外掛的 layout
屬性控制,示例如下所示
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start.class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
layout
屬性預設值由檔案型別(jar
或 war
)決定。以下是可用的佈局
-
JAR
:常規可執行 JAR 佈局。 -
WAR
:可執行 WAR 佈局。provided
依賴項放在WEB-INF/lib-provided
中,以避免war
部署到 servlet 容器時發生衝突。 -
ZIP
(DIR
的別名):類似於使用PropertiesLauncher
的JAR
佈局。 -
NONE
:打包所有依賴項和專案資源。不包含引導載入器。
分層 Jar 或 War
重新打包的 jar 檔案分別在 BOOT-INF/classes
和 BOOT-INF/lib
中包含應用程式的類和依賴項。類似地,可執行 war 檔案在 WEB-INF/classes
中包含應用程式的類,並在 WEB-INF/lib
和 WEB-INF/lib-provided
中包含依賴項。對於需要從 jar 或 war 內容構建 Docker 映象的情況,能夠進一步分離這些目錄以便將它們寫入不同的層是非常有用的。
分層檔案使用與常規重新打包的 jar 或 war 相同的佈局,但包含一個描述每個層的附加元資料檔案。
預設情況下,定義了以下層
-
dependencies
:適用於版本不包含SNAPSHOT
的任何依賴項。 -
spring-boot-loader
:適用於載入器類。 -
snapshot-dependencies
:適用於版本包含SNAPSHOT
的任何依賴項。 -
application
:適用於本地模組依賴項、應用程式類和資源。
模組依賴項透過檢視當前構建中的所有模組來識別。如果某個模組依賴項僅因已安裝到 Maven 的本地快取中且不屬於當前構建而能夠解析,則它將被識別為常規依賴項。
層的順序很重要,因為它決定了當應用程式部分發生變化時,之前層被快取的可能性。預設順序是 dependencies
、spring-boot-loader
、snapshot-dependencies
、application
。最不可能更改的內容應首先新增,然後是更有可能更改的層。
預設情況下,重新打包的檔案會包含 layers.idx
檔案。要停用此功能,可以按以下方式進行
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>false</enabled>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
自定義分層配置
根據您的應用程式,您可能需要調整層的建立方式並新增新層。這可以透過一個單獨的配置檔案來完成,該檔案應按如下方式註冊
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
<configuration>${project.basedir}/src/layers.xml</configuration>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
配置檔案描述瞭如何將檔案分成多個層以及這些層的順序。以下示例顯示瞭如何明確定義上述預設順序
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-3.4.xsd">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
</into>
<into layer="application" />
</application>
<dependencies>
<into layer="application">
<includeModuleDependencies />
</into>
<into layer="snapshot-dependencies">
<include>*:*:*SNAPSHOT</include>
</into>
<into layer="dependencies" />
</dependencies>
<layerOrder>
<layer>dependencies</layer>
<layer>spring-boot-loader</layer>
<layer>snapshot-dependencies</layer>
<layer>application</layer>
</layerOrder>
</layers>
layers
XML 格式定義了三個部分
-
<application>
塊定義了應用程式類和資源應該如何分層。 -
<dependencies>
塊定義了依賴項應該如何分層。 -
<layerOrder>
塊定義了應該寫入層的順序。
巢狀的 <into>
塊用於 <application>
和 <dependencies>
部分,用於為某個層宣告內容。這些塊按定義的順序從上到下進行評估。任何未被較早塊宣告的內容仍可供後續塊考慮。
<into>
塊使用巢狀的 <include>
和 <exclude>
元素宣告內容。<application>
部分使用 Ant 風格的路徑匹配進行包含/排除表示式。<dependencies>
部分使用 group:artifact[:version]
模式。它還提供了 <includeModuleDependencies />
和 <excludeModuleDependencies />
元素,可用於包含或排除本地模組依賴項。
如果未定義 <include>
,則考慮所有內容(未被較早塊宣告的內容)。
如果未定義 <exclude>
,則不應用任何排除項。
檢視上面的 <dependencies>
示例,我們可以看到第一個 <into>
將為 application.layer
宣告所有模組依賴項。下一個 <into>
將為 snapshot-dependencies
層宣告所有 SNAPSHOT 依賴項。最後一個 <into>
將為 dependencies
層宣告剩餘的所有內容(在本例中,即所有非 SNAPSHOT 依賴項)。
<application>
塊具有類似的規則。首先為 spring-boot-loader
層宣告 org/springframework/boot/loader/**
內容。然後為 application
層宣告任何剩餘的類和資源。
<into> 塊的定義順序通常與寫入層的順序不同。因此,必須始終包含 <layerOrder> 元素,並且它 必須 覆蓋 <into> 塊引用的所有層。 |
spring-boot:repackage
org.springframework.boot:spring-boot-maven-plugin:3.4.5
重新打包現有的 JAR 和 WAR 檔案,以便可以使用 java -jar
從命令列執行它們。使用 layout=NONE
也可以簡單地用於打包帶有巢狀依賴項的 JAR(且沒有主類,因此不可執行)。
可選引數
名稱 | 型別 | 預設值 |
---|---|---|
|
|
|
|
||
|
||
|
||
|
|
|
|
|
|
|
||
|
||
|
|
|
|
|
|
|
|
|
|
||
|
||
|
|
|
|
||
|
|
引數詳情
attach
將重新打包的檔案附加到要安裝到本地 Maven 倉庫或部署到遠端倉庫的 artifact。如果未配置分類器,它將替換正常的 jar 檔案。如果配置了 classifier
,使得正常 jar 和重新打包的 jar 不同,它將作為附加 artifact 與正常 jar 一同安裝/部署。當該屬性設定為 false
時,重新打包的檔案將不會被安裝或部署。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
classifier
要新增到重新打包檔案的分類器。如果未指定,主 artifact 將被重新打包檔案替換。如果指定,該分類器也將用於確定要重新打包的源檔案:如果已存在具有該分類器的 artifact,則將其用作源並被替換。如果不存在此類 artifact,則將使用主 artifact 作為源,並將重新打包的檔案作為帶有該分類器的附加 artifact 附加。附加 artifact 允許將其與原始 artifact 一同部署,更多詳細資訊請參閱Maven 文件。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
embeddedLaunchScript
如果 jar 是完全可執行的,要新增到 jar 前面的嵌入式啟動指令碼。如果未指定,將使用 Spring Boot 的預設指令碼。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
embeddedLaunchScriptProperties
應該在嵌入式啟動指令碼中展開的屬性。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDevtools
從重新打包的檔案中排除 Spring Boot devtools。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeDockerCompose
從重新打包的檔案中排除 Spring Boot dev services。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludeGroupIds
要排除的 groupId 名稱的逗號分隔列表(精確匹配)。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
excludes
要排除的 artifact 定義集合。Exclude
元素定義了必需的 groupId
和 artifactId
元件以及可選的 classifier
元件。當配置為屬性時,值應該是逗號分隔的,元件之間用冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
executable
透過在 jar 檔案前新增啟動指令碼,為 *nix 系統建立完全可執行的 jar。目前,某些工具不接受此格式,因此您可能並非總是能夠使用此技術。例如,jar -xf
可能會靜默地無法解壓已設定為完全可執行的 jar 或 war。建議您僅在打算直接執行它時才啟用此選項,而不是透過 java -jar
執行或部署到 servlet 容器。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
includes
要包含的 artifact 定義集合。Include
元素定義了必需的 groupId
和 artifactId
元件以及可選的 classifier
元件。當配置為屬性時,值應該是逗號分隔的,元件之間用冒號分隔:groupId:artifactId,groupId:artifactId:classifier
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
layout
檔案型別(對應於依賴項在其中的佈局方式)。可能的值包括 JAR
、WAR
、ZIP
、DIR
、NONE
。預設為基於檔案型別的猜測值。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputDirectory
包含生成檔案的目錄。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
outputTimestamp
用於可重現輸出檔案條目的時間戳,格式可以是 ISO 8601 (yyyy-MM-dd’T’HH:mm:ssXXX
) 或表示自 epoch 以來的秒數的 int
值。
名稱 |
|
---|---|
型別 |
|
預設值 |
|
使用者屬性 |
|
自 |
|
示例
自定義分類器
預設情況下,repackage
目標將原始 artifact 替換為重新打包的 artifact。對於代表應用程式的模組來說,這是合理的行為,但如果您的模組被用作另一個模組的依賴項,您需要為重新打包的 artifact 提供一個分類器。這是因為應用程式類被打包在 BOOT-INF/classes
中,以便依賴模組無法載入重新打包 jar 中的類。
如果是這種情況,或者您希望保留原始 artifact 並使用不同的分類器附加重新打包的 artifact,請按以下示例配置外掛
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
如果您正在使用 spring-boot-starter-parent
,repackage
目標將自動在 id 為 repackage
的執行中執行。在此設定中,只需指定配置即可,示例如下所示
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置將生成兩個 artifact:原始 artifact 和由 repackage 目標生成的重新打包 artifact。兩者都將透明地安裝/部署。
如果您想以與替換主 artifact 相同的方式重新打包次要 artifact,也可以使用相同的配置。以下配置會安裝/部署一個帶有重新打包應用程式的、被分類為 task
的單個 artifact
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
由於 maven-jar-plugin
和 spring-boot-maven-plugin
都執行在同一階段,重要的是先定義 jar 外掛(以便它在 repackage 目標之前執行)。同樣,如果您正在使用 spring-boot-starter-parent
,可以按如下方式簡化
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<configuration>
<classifier>task</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
自定義名稱
如果您需要重新打包的 jar 的本地名稱與專案 artifactId
屬性定義的名稱不同,請使用標準的 finalName
,示例如下所示
<project>
<build>
<finalName>my-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置將在 target/my-app.jar
中生成重新打包的 artifact。
本地重新打包 artifact
預設情況下,repackage
目標將原始 artifact 替換為可執行 artifact。如果您只需要部署原始 jar,但仍希望能夠使用常規檔名執行應用程式,請按如下方式配置外掛
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
此配置生成兩個 artifact:原始 artifact 和由 repackage
目標生成的可執行 artifact。只有原始 artifact 會被安裝/部署。
自定義佈局
Spring Boot 使用定義在附加 jar 檔案(作為構建外掛的依賴項提供)中的自定義佈局工廠重新打包此專案的 jar 檔案
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<layoutFactory implementation="com.example.CustomLayoutFactory">
<customProperty>value</customProperty>
</layoutFactory>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>custom-layout</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
佈局工廠作為 LayoutFactory
(來自 spring-boot-loader-tools
)的實現提供,在 pom 中明確指定。如果在外掛 classpath 上只有一個自定義 LayoutFactory
,並且它列在 META-INF/spring.factories
中,則無需在外掛配置中顯式設定它。
如果設定了顯式佈局,則始終忽略佈局工廠。
依賴排除
預設情況下,repackage
和 run
目標都會包含專案中定義的任何 provided
依賴項。Spring Boot 專案應將 provided
依賴項視為執行應用程式所需的“容器”依賴項。一般來說,Spring Boot 專案不被用作依賴項,因此不太可能具有任何 optional
依賴項。當專案確實有 optional 依賴項時,repackage
和 run
目標也會包含它們。
其中一些依賴項可能完全不需要,應從可執行 JAR 中排除。為保持一致性,在執行應用程式時也不應包含它們。
有兩種方法可以排除依賴項,使其不被打包或在執行時使用
-
排除由
groupId
和artifactId
標識的特定構件,如果需要,可選擇帶上classifier
。 -
排除屬於給定
groupId
的任何構件。
以下示例排除 com.example:module1
,且僅排除該構件
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>com.example</groupId>
<artifactId>module1</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
此示例排除屬於 com.example
組的任何構件
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeGroupIds>com.example</excludeGroupIds>
</configuration>
</plugin>
</plugins>
</build>
</project>
JAR 工具
建立分層 JAR 或 WAR 時,spring-boot-jarmode-tools
JAR 將作為依賴項新增到您的歸檔中。在類路徑中包含此 JAR,您可以以特殊模式啟動應用程式,該模式允許引導程式碼執行與您的應用程式完全不同的內容,例如,提取分層內容的程式。如果您希望排除此依賴項,可以按以下方式操作
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeTools>false</includeTools>
</configuration>
</plugin>
</plugins>
</build>
</project>
自定義分層配置
預設設定將依賴項分為 snapshot 和非 snapshot,但是,您可能有更復雜的規則。例如,您可能希望在專用分層中隔離專案的公司特定依賴項。以下 layers.xml
配置顯示了這樣一種設定
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-3.4.xsd">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
</into>
<into layer="application" />
</application>
<dependencies>
<into layer="snapshot-dependencies">
<include>*:*:*SNAPSHOT</include>
</into>
<into layer="company-dependencies">
<include>com.acme:*</include>
</into>
<into layer="dependencies"/>
</dependencies>
<layerOrder>
<layer>dependencies</layer>
<layer>spring-boot-loader</layer>
<layer>snapshot-dependencies</layer>
<layer>company-dependencies</layer>
<layer>application</layer>
</layerOrder>
</layers>
以上配置建立了一個額外的 company-dependencies
分層,其中包含所有 groupId 為 com.acme
的庫。