优秀的编程知识分享平台

网站首页 > 技术文章 正文

史上最详细最清晰的SpringBoot项目打包方法

nanyue 2025-05-30 16:34:04 技术文章 10 ℃

很多同学在使用maven给SpringBoot项目打包时,通常将Spring Boot项目打包成一个可执行的JAR文件,这种JAR被称为"fat JAR"或"uber JAR",它包含了项目中的所有依赖和资源文件。虽然这种方式方便部署和运行,但也存在一些缺点:

  1. 文件大小:将所有依赖和资源打包到一个JAR文件中,可能导致JAR文件变得非常大,这会增加传输和部署的时间,尤其是当项目依赖很多库时。
  2. 内存占用:加载一个包含大量依赖的大型JAR文件可能会增加JVM的内存占用,这可能会影响到应用程序的性能。
  3. 更新依赖:每次更新项目的某个依赖时,需要重新构建整个JAR文件,即使该依赖的改动很小。这可能导致频繁的构建和部署,消耗更多的时间和资源。
  4. 不易识别和管理依赖:将所有依赖打包到一个JAR文件中,使得在运行时很难识别和管理这些依赖。当出现依赖冲突或需要排查依赖问题时,可能会变得困难。

尽管存在这些缺点,将Spring Boot项目打包成一个JAR文件仍然是一种非常流行的部署方式,因为它简化了部署过程,降低了部署的复杂性。不过,根据项目的实际需求,你可以考虑使用其他打包和部署方式,如将应用打包成WAR文件部署到外部应用服务器,或者将主程序、依赖包和资源文件分离开来。

在使用Maven打包程序时,将程序文件和资源文件分离的一种方法是将它们分别放入不同的输出目录。这可以通过修改pom.xml文件来实现。

下面给大家介绍一下主程序、依赖包和资源文件分离打包的方式,方式有两种:

第一种:

可以使用maven-assembly-plugin插件。以下是一个示例,说明了如何进行操作:

  1. 首先,在src/main目录下确保有两个子目录:java用于存放Java源代码,resources用于存放资源文件。
  2. pom.xml文件中,使用maven-assembly-plugin插件将主程序、依赖包和资源文件分离。修改pom.xml文件,添加以下内容:
<build>
    <plugins>
        <!-- Spring Boot插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        
        <!-- Maven Assembly插件 -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.example.MainClass</mainClass>
                    </manifest>
                </archive>
                <outputDirectory>${project.build.directory}/app</outputDirectory>
                <finalName>my-app</finalName>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

在这个例子中,<mainClass>com.example.MainClass</mainClass>这一行需要替换为你项目的实际主类。

  1. 在项目根目录下创建一个名为assembly.xml的文件,用于定义如何分离文件:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>app-with-dependencies</id>
    <formats>
        <format>dir</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <!-- 拷贝主程序 -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>app</outputDirectory>
            <includes>
                <include>my-app.jar</include>
            </includes>
        </fileSet>
        <!-- 拷贝依赖包 -->
        <fileSet>
            <directory>${project.build.directory}/dependency</directory>
            <outputDirectory>lib</outputDirectory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
        <!-- 拷贝资源文件 -->
        <fileSet>
            <directory>src/main/resources</directory>
            <outputDirectory>resources</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>
  1. 运行mvn clean package命令,Maven将会编译Java源代码、打包主程序、依赖包和资源文件。在target目录下,你将看到以下结构:
target
└── app
    ├── my-app.jar        // 主程序
    ├── lib              // 存放依赖的库文件
    │   ├── dependency1.jar
    │   ├── dependency2.jar
    │   └── ...
    └── resources        // 存放资源文件
        ├── application.properties
        ├── ...

通过这种方式,我们将主程序、依赖包和资源文件分离开来。主程序位于my-app.jar文件中,依赖包位于lib目录下,资源文件位于resources目录下。你可以根据需要进一步自定义assembly.xml文件,以满足你的项目需求。


第二种:

如果不使用maven-assembly-plugin插件,你可以使用maven-dependency-pluginmaven-resources-plugin插件来达到同样的效果。以下是一个示例:

  1. pom.xml文件中,使用maven-dependency-plugin插件将依赖包复制到一个单独的目录,使用maven-resources-plugin插件将资源文件复制到另一个单独的目录。修改pom.xml文件,添加以下内容:
<build>
    <plugins>
        <!-- Spring Boot插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <!-- 将依赖包复制到单独的目录 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.2</version>
            <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>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/resources</outputDirectory>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <filtering>true</filtering>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  1. 运行mvn clean package命令,Maven将会编译Java源代码、打包主程序、依赖包和资源文件。在target目录下,你将看到以下结构:
target
├── my-app.jar        // 主程序
├── lib              // 存放依赖的库文件
│   ├── dependency1.jar
│   ├── dependency2.jar
│   └── ...
└── resources        // 存放资源文件
    ├── application.properties
    ├── ...

通过这种方式,我们将主程序、依赖包和资源文件分离开来。主程序位于my-app.jar文件中,依赖包位于lib目录下,资源文件位于resources目录下。这种方法不使用maven-assembly-plugin插件,而是使用maven-dependency-pluginmaven-resources-plugin插件来实现。

这两种方式都可以实现将主程序、依赖包和资源文件分离的目标,但它们在实现方式和适用场景上有所不同。以下是对这两种方式的对比:

使用maven-assembly-plugin

优点:

  1. 可以将主程序、依赖包和资源文件分离到不同的目录或打包成不同的压缩包格式。
  2. 插件功能强大,可以用于实现复杂的打包需求。
  3. 支持定制化程度高,可以灵活地指定包含或排除哪些文件。

缺点:

  1. 配置相对复杂,需要创建assembly.xml文件来指定打包规则。
  2. 使用maven-dependency-pluginmaven-resources-plugin
  3. 优点:
  4. 配置相对简单,不需要额外创建assembly.xml文件。
  5. 插件功能相对单一,易于理解和维护。
  6. 缺点:
  7. 定制化程度相对较低,可能不适合处理复杂的打包需求。
  8. 需要使用两个插件来完成任务。

总结:

  • 如果你的项目打包需求较为简单,不需要高度定制化的打包过程,那么使用maven-dependency-pluginmaven-resources-plugin插件可能更合适,配置简单且易于维护。
  • 如果你的项目打包需求较为复杂,需要高度定制化的打包过程,或者需要将文件打包成不同的压缩包格式,那么使用maven-assembly-plugin插件可能更合适,功能强大且支持定制化程度高。

根据你的项目需求和个人喜好选择合适的方式。

Tags:

最近发表
标签列表