首页 > 编程笔记 > Java笔记 阅读:5

Spring Boot项目打包详解(实例演示)

Spring Boot 使用了内嵌容器,因此它的部署方式也变得非常简单灵活,可以将 Spring Boot 项目打包成 JAR 包来独立运行,也可以打包成 WAR 包部署到 Tomcat 容器中运行,如果涉及大规模的部署,Jenkins 成为最佳选择之一。

现在 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

命令执行完成后,JAR 包会生成到 target 目录下,命名一般是“项目名+版本号.jar”的形式,如下图所示:


图 1 maven打包生成的目录

生成WAR包

Spring Boot 项目既可以生成 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 个功能:
最后,在控制台执行如下命令:

mvn clean package -Dmaven.test.skip=true

命令执行完之后,就可以看到 target 目录下生成了 JAR 包、资源文件和配置文件,而且生成的 JAR 包变得非常小,如下图所示。


图 4 JAR包、资源文件和配置文件

相关文章