Spring Boot Maven Plugin打包解析
一. 简介
The Spring Boot Maven Plugin provides Spring Boot support in Apache Maven. It allows you to package executable jar or war archives, run Spring Boot applications, generate build information and start your Spring Boot application prior to running integration tests.
Spring Boot Maven Plugin 插件在 Apache Maven 中提供 Spring Boot 支持。它允许打包可执行的 jar 或 war 包, 运行 Spring Boot 应用程序, 生成构建信息并在运行集成测试之前启动 Spring Boot 应用程序.
二. Spring Boot Maven Plugin的引用
在使用 Spring Boot Maven Plugin 前, 需要在工程项目的pom.xml文件 plugins 中, 引用该插件. 如下所示:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.spring.boot</groupId>
<artifactId>spring-boot-demo</artifactId>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
如果使用的是 里程碑或快照版本 , 另需要配置 Maven Repository 定向至 Spring 的仓库地址. 如下所示:
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
三. Spring Boot Maven Plugin的使用
Maven 用户可以从 spring-boot-starter-parent 项目继承以获得合理的默认配置. 父项目提供以下功能:
- Java 1.8 as the default compiler level.
- UTF-8 source encoding.
- A dependency management section, inherited from the spring-boot-dependencies POM, that manages the versions of common dependencies. This dependency management lets you omit <version> tags for those dependencies when used in your own POM.
- An execution of the repackage goal with a repackage execution id.
- Sensible resource filtering.
- Sensible plugin configuration (Git commit ID, and shade).
- Sensible resource filtering for application.properties and application.yml including profile-specific files (for example, application-dev.properties and application-dev.yml)
- 以 Java 1.8 作为默认编译版本
- 以 UTF-8 作为源编码方式
- 继承自 spring-boot-dependencies POM , 用于管理公共依赖项的版本控制. 有此依赖管理, 可以在自己的 pom.xml 中, 省略受版本控制的依赖项的 <version> 标签.
- repackage 目标(goal)中配置有 repackage ID执行目标.
- 适当的资源过滤.
- 适当的插件配置 (Git commit ID, and shade).
- 对 application.properties 和 application.yml 合理的资源过滤, 包括 application-dev.properties 和 application-dev.yml 等特定配置资源.
3.1. 继承 Starter Parent POM
配置工程中继承 spring-boot-starter-parent , pom.xml 中添加 parent, 配置如下:
<project>
<!-- ... -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
</parent>
<!-- ... -->
</project>
- 只需要为此依赖项指定 Spring Boot 版本号, 导入其他依赖项, 则可以安全地省略版本号. 如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
通过该配置, 还可以通过覆盖自己项目中的属性(properties)来覆盖各个依赖项. 例如, 要使用不同版本的 SLF4J 库和 Spring Data 发布系列, 需要将以下内容添加到 pom.xml 中:
<project>
<!-- ... -->
<properties>
<slf4j.version>1.7.31</slf4j.version>
<spring-data-releasetrain.version>Neumann-SR9</spring-data-releasetrain.version>
</properties>
<!-- ... -->
</project>
3.2. 在没有 Starter Parent POM 的情况下使用 Spring Boot
如果不想以 spring-boot-starter-parent 作为 Parent POM , 但又想保留 Spring Boot Parent 的依赖项版本管理功能, 可以通过 <scope>import</scope> 方式引入, 该方式只能实现依赖管理(dependencies), 并不包含插件管理(plugins), 如下:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
前面的示例设置不允许使用属性(properties)覆盖各个依赖项,如上所述, 要达到相同的结果,需要在 dependencyManagement 中, spring-boot-dependencies 依赖项之前添加依赖项, 用以覆盖 spring-boot-dependencies 中的默认依赖项. 例如, 要使用不同版本的 SLF4J 库和 Spring Data 发布系列, 需要将以下内容添加到 pom.xml 中:
<dependencyManagement>
<dependencies>
<!-- Override SLF4J provided by Spring Boot -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.31</version>
</dependency>
<!-- Override Spring Data release train provided by Spring Boot -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Neumann-SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.3. 在命令行上覆盖配置内容运行
该插件(plugin)提供了大量的用户属性(user properties), 用以 spring-boot 启动, 并且允许用户在命令行中重新指定这些属性(user properties)并启动 spring-boot .
例如, 可以在运行应用程序时调整启动配置文件, 如下所示:
$ mvn spring-boot:run -Dspring-boot.run.profiles=dev,local
如果希望允许在命令行上覆盖的同时, 又具有默认值, 则可以结合使用用户提供的项目属性(properties)和 MOJO 配置. 如下:
<project>
<properties>
<app.profiles>local,dev</app.profiles>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<profiles>${app.profiles}</profiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
以上确保默认情况下启用 local 和 dev 的同时, 并对外公开了一个专用属性 app.profiles , 使得这也可以在命令行上覆盖该属性, 以实现指定配置文件并运行:
$ mvn spring-boot:run -Dapp.profiles=test
四. Spring Boot Maven Plugin中的Goals
Goal | Description |
---|---|
spring-boot:build-image | Package an application into a OCI image using a buildpack. 使用某一buildpack将应用程序打包到OCI映像中, 例如: Docker. |
spring-boot:build-info | Generate a build-info.properties file based on the content of the current MavenProject. 根据当前 Maven Project 生成 build-info.properties 文件, 文件常位于target/classes/META-INF/build-info.properties. |
spring-boot:help | Display help information on spring-boot-maven-plugin. Call mvn spring-boot:help -Ddetail=true -Dgoal=<goal-name> to display parameter details.显示有关 spring-boot-maven-plugin 的帮助信息. 通过执行 mvn spring-boot:help -Ddetail=true -Dgoal=<goal-name> , 显示指定<goal-name> 的详细信息. |
spring-boot:repackage | Repackage existing JAR and WAR archives so that they can be executed from the command line using java -jar . With layout=NONE can also be used simply to package a JAR with nested dependencies (and no main class, so not executable).重新打包现有 JAR 和 WAR 包, 以方便其可以通过 java -jar 执行. 也可以指定 layout=NONE 简单打包具有嵌套依赖的的 JAR 包(包内不含mainClass, 所以无法通过java -jar 执行). |
spring-boot:run | Run an application in place. 在适当的位置运行应用程序. |
spring-boot:start | Start a spring application. Contrary to the run goal, this does not block and allows other goals to operate on the application. This goal is typically used in integration test scenario where the application is started before a test suite and stopped after. 启动一Spring应用程序. 与run相反, start不会阻止并且允许其他goals操作应用程序. start通常用于集成测试场景, 其中应用程序在测试套件之前启动并在测试套件之后停止. 因此 mvn spring-boot:start 执行成功后, 会后台模式运行.运行时, 若有问题, 可尝试: mvn clean complie spring-boot:start |
spring-boot:stop | Stop an application that has been started by the “start” goal. Typically invoked once a test suite has completed. 停止一个由 start 启动的应用程序. 通常在测试套件完成后调用. |
五. 打包可执行文件
该插件(plugin)可以创建可执行的 jar包 或 war包 , 其中包含应用程序执行所需要的所有的依赖项, 然后可通过java -jar
执行. 打包成可执行的 jar包 或 war包, 是由 repackage 目标(goal)重新打包生成的. 如下所示:
<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>
- 如果工程项目中使用了 spring-boot-starter-parent 作为 parent, repackage 目标(goal)执行ID已经事先配置好, 这里只需要引用插件(plugin)即可, 无需再配置 executions . 如下所示:
<build> <plugins> <plugin> <groupId>org.springframework.boot