Spring Boot | 项目打包的两种方式:丰满or苗条,你选哪种?

248 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

将Spring Boot项目打包成可执行的Jar文件

在 Spring Boot 应用中,Spring Boot 自带的spring-boot-maven-plugin插件使打包程序变得非常简单。我们只需要在项目pom.xml文件中加入如下配置:

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

无须加入其它配置就能将整个项目打包成可执行的Jar文件。

Jar文件是一种后缀名为jar的打包文件格式,打包内容包含工程已编译的依赖库、资源文件、元数据文件以及压缩好的应用程序类文件。

pom.xml添加spring-boot-maven-plugin插件后,通过如下命令打包程序:

mvn clean package

打包后,会在项目target目录下生成Jar文件。

执行Jar文件可以执行如下命令:

java -jar your_jar_file_name.jar

我个人挺喜欢这种部署方式的,简单、省心。打的Jar文件——不考虑数据库、Redis等其它运行环境——可以在任何任何装有JDK的机器上运行。

给打包后的Spring Boot项目Jar文件“瘦身”

但是在一些网络不好、网速比较慢的情况下,包含所有依赖Jar包的可执行Jar文件就显得有些冗余了。这个时候我们可能就需要给打包后的Jar文件“瘦身”了。

给打包后的Jar文件“瘦身”我们只需要在pom.xml文件中添加如下配置即可:

<build>
    <plugins>
        <!-- 其它插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <configuration>
                <layout>ZIP</layout>
                <includes>
                	<!-- 这里只包含一个不存在的项nothing,即代表什么都不包含,当然名字可以随便写 -->
                    <include>
                        <groupId>nothing</groupId>
                        <artifactId>nothing</artifactId>
                    </include>
                </includes>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!--拷贝依赖到libs目录-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-lib</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>target/libs</outputDirectory>
                        <excludeTransitive>false</excludeTransitive>
                        <stripVersion>false</stripVersion>
                        <includeScope>runtime</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

这样我们打包后的 spring boot 项目较之前就小太多了。我们只需要在第一次部署项目的时候把libs文件夹复制到服务器,以后再部署项目只需要复制项目自身的Jar文件就好了。

打包后的项目运行脚本示例:

java -Djava.ext.dirs=./libs -jar your_jar_file_name.jar

另外,下面三款插件也是笔者经常用到的插件。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <!-- 打包发布时,跳过单元测试 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

Maven插件说明

(1)maven-dependency-plugin

The dependency plugin provides the capability to manipulate artifacts. It can copy and/or unpack artifacts from local or remote repositories to a specified location. 引自官网

maven-dependency-plugin是一个用于操作依赖的插件,它能复制/解压依赖到指定目录。

(2)maven-resources-plugin

maven-resources-plugin用来处理资源文件。

(3)maven-surefire-plugin

maven-surefire-plugin主要用于打包发布时,跳过单元测试。

spring boot打包后读取不到classpath路径下的文件

一旦打成jar包后,使用File是访问不到资源的内容的,推荐使用getInputStream()的方法。

读取方式:

ClassPathResource resource = new ClassPathResource("your_classpath_file_name.xml");
InputStream inputStream = resource..getInputStream();