1、說明
SpringBoot 的 Maven 插件能夠以 Maven 的方式為應用提供 SpringBoot 的支持,即為 SpringBoot 應用提供了執行 Maven 操作的可能。
SpringBoot 的 Maven plugin能夠將 SpringBoot 應用打包為可執行的 jar 或 war 包,然后以通常的方式如 java -jar 來運行 SpringBoot 應用。
2、對應插件
Spring Boot Maven plugin 的 5個 Goals:
- repackage,默認 goal。在 mvn package 之后,再次打包可執行的 jar/war,同時保留 mvn package 生成的 jar/war 為 .origin
- run,運行 SpringBoot 應用
- start,在 mvn integration-test 階段,進行 SpringBoot 應用生命周期的管理
- stop,在 mvn integration-test 階段,進行 SpringBoot 應用生命周期的管理
- build-info,生成 Actuator 使用的構建信息文件 build-info.properties
3、相關配置
對應 pom.xml 文件配置如下:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.xxx.bs.SearchBsBootstrap</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
4、repackage 說明
Spring Boot Maven plugin的最主要 goal 就是 repackage,其在 Maven 的 package 生命周期階段,能夠將 mvn package 生成的軟件包,再次打包為可執行的軟件包,並將 mvn package 生成的軟件包重命名為 *.original
基於上述配置,對一個生成Jar軟件包的項目執行如下命令。
mvn package spring-boot:repackage
可以看到生成的兩個jar文件,一個是 *.jar,另一個是 *.jar.original。
在執行上述命令的過程中,Maven首先在package階段打包生成*.jar文件;然后執行 spring-boot:repackage 重新打包,查找 Manifest 文件中配置的 Main-Class 屬性,如下所示:
Manifest-Version: 1.0 Implementation-Title: search-bs Implementation-Version: 0.1.0 Archiver-Version: Plexus Archiver Built-By: sam Implementation-Vendor-Id: org.springframework Spring-Boot-Version: 2.1.2.RELEASE Implementation-Vendor: Pivotal Software, Inc. Main-Class: org.springframework.boot.loader.JarLauncher Start-Class: com.xxx.bs.SearchBsBootstrap Spring-Boot-Classes: BOOT-INF/classes/ Spring-Boot-Lib: BOOT-INF/lib/ Created-By: Apache Maven 3.6.0 Build-Jdk: 1.8.0_155
注意,其中的 Main-Class 屬性值為 org.springframework.boot.loader.JarLauncher;
Start-Class屬性值為 com.xxx.bs.SearchBsBootstrap
其中 com.xxx.bs.SearchBsBootstrap 類中定義了 main() 方法,是程序的入口。
通常,SpringBoot Maven plugin 會在打包過程中自動為 Manifest 文件設置 Main-Class 屬性,事實上該屬性究竟作用幾何,還可以受 SpringBoot Maven plugin 的配置屬性 layout 控制的,示例如下:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.2.RELEASE</version> <configuration> <mainClass>${start-class}</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
注意,這里的layout屬性值為 ZIP。
layout屬性的值可以如下:
- JAR,即通常的可執行jar
Main-Class: org.springframework.boot.loader.JarLauncher
- WAR,即通常的可執行 war,需要的servlet容器依賴位於WEB-INF/lib-provided
Main-Class: org.springframework.boot.loader.warLauncher
- ZIP,即 DIR,類似於JAR
Main-Class: org.springframework.boot.loader.PropertiesLauncher
MODULE,將所有的依賴庫打包(scope為provided的除外),但是不打包Spring Boot的任何Launcher。
NONE,將所有的依賴庫打包,但是不打包Spring Boot的任何Launcher。
5、問題解答
springboot 打 jar 包,無法引用jar包里面的類,為什么?
問題描述:
我的目錄結構是一個父項目,下面有三個子項目client,common,server。client是對外提供的所有接口。在將這個項目打包之后,client的包對外提供。現在的問題是別的項目依賴了這個包之后無法引用里面的普通類。並且在打包時必須先compile才能install,不然install時client會報無法引用common中的類。
問題解答:
因為使用了上面提到的 springboot 打包的方式,我們得明白這里的jar並不是普通意義上的 jar 包或者說不是Java中的公共類庫,而是一個獨立的Web應用。 實際上,這里的 jar 更應該是 war。只是由於 SpringBoot 的設計思想,應用使用了jar。 如果你的 jar 不是以服務的方式被訪問,那么就完全不必使用 SpringBoot插件重新打包了,因為根本沒有入口類,也不需要可執行的jar。所以針對這種情況需要視情況而定:
1. 打的包如果是一個可運行的 jar 包,那么內部的公共類庫需要抽離封裝到應該是公共類庫的 jar 包中,這個可運行的 jar 包或者是 war 包是對外提供服務的,是無法直接依賴引用的。
2. 如果只是一個普通公共類庫 jar 包,那么只需要將 pom 文件中使用 springboot repackage 打包方式修改為 maven 普通打包方式即可,即:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
