Spring Boot项目打包详解(实例演示)
Spring Boot 使用了内嵌容器,因此它的部署方式也变得非常简单灵活,可以将 Spring Boot 项目打包成 JAR 包来独立运行,也可以打包成 WAR 包部署到 Tomcat 容器中运行,如果涉及大规模的部署,Jenkins 成为最佳选择之一。
现在 Maven、Gradle 已经成为我们日常开发必不可少的构建工具,使用这些工具很容易将项目打包成 JAR 或者 WAR 包。下面以 Maven 项目为例演示 Spring Boot 项目如何打包发布。
然后,在项目根目录下,在控制台执行如下命令:
命令执行完成后,JAR 包会生成到 target 目录下,命名一般是“项目名+版本号.jar”的形式,如下图所示:

图 1 maven打包生成的目录
Spring Boot 生成 WAR 包的方式和生成 JAR 包的方式基本一样,只需要添加一些额外的配置。下面演示生成 WAR 包的方式。

图 2 maven打包生成的目录

图 3 配置文件与jar包分离
lib 目录为依赖 JAR 包目录,conf 目录存放系统配置文件,html 目录为存放静态资源文件的目录。这样就把配置文件、资源文件与 JAR 包分离,如果需要修改配置文件、JS、CSS 等文件,直接修改相关文件即可,无须重新打包。
Spring Boot 通过重新定义 Maven 插件能够轻松实现静态文件、配置文件与 JAR 包的分离,只需要修改项目中的 pom.xml 文件,将 pom.xml 配置文件中的 <build> 节点修改为自定义 maven 打包插件即可,配置示例如下:
最后,在控制台执行如下命令:

图 4 JAR包、资源文件和配置文件
现在 Maven、Gradle 已经成为我们日常开发必不可少的构建工具,使用这些工具很容易将项目打包成 JAR 或者 WAR 包。下面以 Maven 项目为例演示 Spring Boot 项目如何打包发布。
生成JAR包
Maven 默认会将项目打成 JAR 包,也可以在 pom.xml 文件中指定打包方式。配置示例如下:<groupId>com.weiz</groupId> <artifactId>spring-boot-package</artifactId> <version>1.0.0</version> <name>spring-boot-package</name> <!--指定打包方式--> <packaging>jar</packaging>在上面的示例中,使用 packaging 标签指定打包方式,版本号为 1.0.0。Maven 打包会根据 pom 包中的 packaging 配置来决定是生成 JAR 包或者 WAR 包。
然后,在项目根目录下,在控制台执行如下命令:
mvn clean package -Dmaven.test.skip=true
- mvn clean package 其实是两条命令,mvn clean 用于清除项目 target 目录下的文件,mvn package 是打包命令。两个命令可以一起执行。
- -Dmaven.test.skip=true:排除测试代码后进行打包。
命令执行完成后,JAR 包会生成到 target 目录下,命名一般是“项目名+版本号.jar”的形式,如下图所示:

图 1 maven打包生成的目录
生成WAR包
Spring Boot 项目既可以生成 WAR 包发布,也可以生成 JAR 包发布,它们的区别是:- JAR 包:通过内置 Tomcat 运行,不需要额外安装 Tomcat。如果需修改内置 Tomcat 的配置,只需要在 Spring Boot 的配置文件中配置即可。内置 Tomcat 没有自己的日志输出,全靠 JAR 包应用输出日志,但是部署简单方便,适合快速部署;
- WAR 包:传统的应用交付方式,需要安装 Tomcat,然后将 WAR 包放到 webapps 目录下运行,这样可以灵活选择 Tomcat 版本,也可以直接修改 Tomcat 的配置,同时有自己的 Tomcat 日志输出,可以灵活配置安全策略。WAR 包相对 JAR 包来说没那么快速方便。
Spring Boot 生成 WAR 包的方式和生成 JAR 包的方式基本一样,只需要添加一些额外的配置。下面演示生成 WAR 包的方式。
1) 修改项目中的pom.xml文件
将 <packaging>jar</packaging> 改为 <packaging>war</packaging>,示例代码如下:<groupId>com.weiz</groupId> <artifactId>spring-boot-package</artifactId> <version>1.0.0</version> <name>spring-boot-package</name> <!--指定打包方式--> <packaging>war</packaging>在上面的示例中,修改 packaging 标签,将 JAR 包的形式改成 WAR 包的形式,版本号为 1.0.0。
2) 排除Tomcat
部署 WAR 包在 Tomcat 中运行,并不需要 Spring Boot 自带的 Tomcat 组件,所以需要在 pom.xml 文件中排除自带的 Tomcat。示例代码如下:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>在上面的示例中,将 Tomcat 组件的 scope 属性设置为 provided,这样在打包产生的 WAR 中就不会包含 Tomcat 相关的 JAR。
3) 注册启动类
在项目的启动类中继承 SpringBootServletInitializer 并重写 configure( ) 方法:@SpringBootApplication public class PackageApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(PackageApplication.class); } public static void main(String[] args) { SpringApplication.run(PackageApplication.class, args); } }
4) 生成WAR包
生成 WAR 包的命令与 JAR 包的命令是一样的,具体命令如下:mvn clean package -Dmaven.test.skip=true执行完成后,会在 target 目录下生成:项目名+版本号.war文件(见下图),将打包好的 WAR 包复制到 Tomcat 服务器中的 webapps 目录下启动即可。

图 2 maven打包生成的目录
实现静态文件、配置文件、JAR包分离
Spring Boot 打包时,默认会把 resources 目录下的静态资源文件和配置文件统一打包到 JAR 文件中。这样部署到生产环境后,一旦需要修改配置文件就会非常麻烦。所以,在实际项目中,会将静态文件、配置文件和 JAR 包分离,如下图所示。
图 3 配置文件与jar包分离
lib 目录为依赖 JAR 包目录,conf 目录存放系统配置文件,html 目录为存放静态资源文件的目录。这样就把配置文件、资源文件与 JAR 包分离,如果需要修改配置文件、JS、CSS 等文件,直接修改相关文件即可,无须重新打包。
Spring Boot 通过重新定义 Maven 插件能够轻松实现静态文件、配置文件与 JAR 包的分离,只需要修改项目中的 pom.xml 文件,将 pom.xml 配置文件中的 <build> 节点修改为自定义 maven 打包插件即可,配置示例如下:
<build> <plugins> <!-- 定义项目的编译环境 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- 打 JAR 包 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <!-- 不打包资源文件(配置文件和依赖包分开) --> <excludes> <exclude>*.yml</exclude> <exclude>*.properties</exclude> <exclude>mapper/**</exclude> <exclude>static/**</exclude> </excludes> <archive> <manifest> <addClasspath>true</addClasspath> <!-- MANIFEST.MF 中 Class-Path 加入前缀 --> <classpathPrefix>lib/</classpathPrefix> <!-- JAR 包不包含唯一版本标识 --> <useUniqueVersions>false</useUniqueVersions> <!-- 指定入口类 --> <mainClass>com.weiz.example01.Example01Application</mainClass> </manifest> <manifestEntries> <!-- MANIFEST.MF 中 Class-Path 加入资源文件目录 --> <Class-Path>./html/</Class-Path> </manifestEntries> </archive> <outputDirectory>${project.build.directory}</outputDirectory> </configuration> </plugin> <!-- 复制依赖的 JAR 包到指定文件夹 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib/</outputDirectory> </configuration> </execution> </executions> </plugin> <!-- 复制指定的资源文件 --> <plugin> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>mapper/**</include> <include>static/**</include> <include>templates/**</include> <include>*.yml</include> <include>*.properties</include> </includes> </resource> </resources> <outputDirectory>${project.build.directory}/html</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>上面的示例通过重新定义 maven 打包插件实现资源文件与 JAR 包的分离。看起来很复杂,其实就实现了 3 个功能:
- 打包时排查 src/main/resources 目录下的静态文件和配置文件;
- 将项目中的依赖库复制到 lib 目录下;
- 将 src/main/resources 目录下的静态文件和配置文件复制到 target 目录下。
最后,在控制台执行如下命令:
mvn clean package -Dmaven.test.skip=true
命令执行完之后,就可以看到 target 目录下生成了 JAR 包、资源文件和配置文件,而且生成的 JAR 包变得非常小,如下图所示。
图 4 JAR包、资源文件和配置文件