这篇文章主要介绍我们在使用 Spring Boot 创建项目时,由于采用创建项目方式的差异,会存在 Spring Boot 项目打包时无法把项目中所依赖的jar包文件一起打包到最终运行的jar包文件中的情况的解决方案。

本文会通过示例的方式进行说明,为正在因此苦恼的童鞋提供有效的解决方案。

Spring Boot 默认项目结构打包

通常情况下,我们直接使用 https://start.spring.io/ 或者IntelliJ IDEASpring Tools 4 Suite 创建 Spring Boot 项目后生成的 pom.xml 文件中,需要注意两个部分:

  1. packaging项目打包类型,默认是jar类型。因此如果项目最终会打包成jar包文件时,在pom.xml<packaging>jar</packaging>可显示声明或者默认不加入。
  2. build节点配置,默认为如下代码:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    这里添加了spring-boot-maven-plugin插件之后,当运行 mvn package 进行打包时会生成一个可直接运行的 jar 包文件,此时可以在 command 窗口运行 java -jar ./spring-boot-packaging-0.0.1-SNAPSHOT.jar 即可直接运行。

注意:此时使用 Spring Boot 创建的项目 pom.xml 文件的 parent 节点直接继承自spring-boot-starter-parent

Spring Boot 多模块项目结构打包

在使用 Maven 进行 Spring Boot 项目结构管理时,常常会使用 model 对项目模块进行划分,此时 Spring Boot 项目 pom.xml 文件的 parent 节点为自定义节点,spring-boot-starter-parent 会放在 dependencyManagement 中进行统一管理,此种情况下再打包 Spring Boot model 项目时就需要在 pom.xml 文件中添加如下配置:

    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <configuration>
             <mainClass>com.saiyueze.spring.boot.packaging.SpringBootPackagingApplication</mainClass><!-- 项目启动主类完整路径 -->
          </configuration>
          <executions>
            <execution>
              <goals>
                <goal>repackage</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>

此时在执行 mvn package 进行打包时即可生成一个可直接运行的 jar 包文件。

注意: 自定义 parent 多模块 Maven 项目中如果不按照此种方式进行配置,一般会出现打包后的 jar 包文件运行时报错,找不到响应的依赖等问题。

扩展阅读:
Maven 项目打包类型分为pomjarwar三种。
<packaging>pom</packaging> 项目为父类型。
<packaging>jar</packaging> 项目作为内部引用或是用作服务可独立运行的打包类型。
<packaging>war</packaging> 需要部署的项目类型。

打包类型主要用于 Maven 进行项目模块划分管理,<packaging>pom</packaging> 是将多个 model 合并,通过它来访问 <modules> 里配置的各个子项目。另外需要注意 pom 项目中是没有 java 代码的,且也不执行任何代码,它只是为了聚合工程或传递依赖用的。

参考连接:
https://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins.html#build-tool-plugins-maven-plugin

https://docs.spring.io/spring-boot/docs/2.2.4.RELEASE/reference/html/using-spring-boot.html#using-boot-maven-without-a-parent

https://docs.spring.io/spring-boot/docs/2.2.4.RELEASE/reference/html/howto.html#howto-create-an-executable-jar-with-maven