前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot - 瘦身大作战:优雅应对Spring Boot Fat Jar

Spring Boot - 瘦身大作战:优雅应对Spring Boot Fat Jar

作者头像
小小工匠
发布2023-11-26 12:17:48
5630
发布2023-11-26 12:17:48
举报
文章被收录于专栏:小工匠聊架构
在这里插入图片描述
在这里插入图片描述

Fat Jar

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

【pom.xml】

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.artisan</groupId>
    <artifactId>thinBootJar</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>thinBootJar</name>
    <description>thinBootJar</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

打包后观察目录

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重点关注下Main-Class


瘦身

pom修改

代码语言:javascript
复制
 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 用来配置可执行jar包中Main-Class的类型,这里一定要设置为 ZIP,使打的jar包中的Main-Class为PropertiesLauncher
 -->
                    <layout>ZIP</layout>
                    <includes>
                        <!-- 不打依赖包 -->
                        <include>
                            <!-- nothing 代表不存在的依赖包,意思就是什么依赖包都不引入-->
                            <groupId>nothing</groupId>
                            <artifactId>nothing</artifactId>
                        </include>
                        <!--                        <include>-->
                        <!-- common是引入的公共服务模块 -->
                        <!--                            <groupId>com.xxx.xx.rpc</groupId>-->
                        <!--                            <artifactId>common</artifactId>-->
                        <!--                        </include>-->
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>

JAR,即通常的可执行jar Main-Class: org.springframework.boot.loader.JarLauncher

WAR,即通常的可执行war,需要的servlet容器依赖位于WEB-INF/lib-provided Main-Class: org.springframework.boot.loader.warLauncher

ZIP,即DIR,类似于JAR Main-Class: org.springframework.boot.loader.PropertiesLauncher

MODULE,将所有的依赖库打包(scope为provided的除外),但是不打包Spring Boot的任何Launcher

NONE,将所有的依赖库打包,但是不打包Spring Boot的任何Launcher


打包后观察下 jar包 的大小 和 里面的内容

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重点关注下Main-Class


copy lib

代码语言:javascript
复制
 <!-- 将依赖的jar包copy到lib目录下  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- 指定依赖的路径 -->
                            <outputDirectory>
                                ${project.build.directory}/lib
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

打包后观察下

在这里插入图片描述
在这里插入图片描述

启动 -Dloader.path

为了让名字好看一点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
java -Dloader.path=./lib  -jar  artisan-test-thin-boot-jar.jar
在这里插入图片描述
在这里插入图片描述

验证

在这里插入图片描述
在这里插入图片描述

通过启动参数loader.path配置外置依赖包的加载路径。 项目成功启动,说明我们配置的外包依赖包加载生效了

spring-boot-loader 依赖

为了方便查看源码,我们引入如下依赖

代码语言:javascript
复制
  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-loader -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-loader</artifactId>
        </dependency>

类继承关系

在这里插入图片描述
在这里插入图片描述

org.springframework.boot.loader.Launcher类是特殊的引导程序类,用作可执行jar的主要入口点。它是jar文件中的实际Main-Class,用于设置适当的URLClassLoader并最终调用main()方法

  • 有三个启动器子类(JarLauncherWarLauncherPropertiesLauncher)。它们的目的是从目录中的嵌套jar文件或war文件(而不是在类路径中显式的文件)加载资源(.class文件等)。
  • 对于JarLauncherWarLauncher,嵌套路径是固定的。 JarLauncher位于BOOT-INF / lib /中,而WarLauncher位于WEB-INF / lib /WEB-INF / lib-provided /中。如果需要,可以在这些位置添加额外的罐子。
  • 默认情况下,PropertiesLauncher在应用程序存档中的BOOT-INF / lib /中查找。可以通过在loader.properties(这是目录,归档文件或归档文件中的目录的逗号分隔列表)中设置一个称为LOADER_PATHloader.path的环境变量来添加其他位置

概括一下: 启动器Launcher是为了项目启动加载依赖资源的,共有3个启动器 JarLauncher,WarLauncher和PropertiesLauncher ,

  • JarLauncher和WarLauncher加载资源的路径是固定的,
  • PropertiesLauncher可以通过环境变量loader.path来指定加载资源的位置

layout属性值说明:

  • JAR,即通常的可执行jar Main-Class: org.springframework.boot.loader.JarLauncher
  • WAR,即通常的可执行war,需要的servlet容器依赖位于 Main-Class: org.springframework.boot.loader.warLauncher
  • ZIP,即DIR,类似于JAR Main-Class: org.springframework.boot.loader.PropertiesLauncher

PropertiesLauncher属性配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  1. loader.path: 用于定义lib包加载路径。
  2. loader.home: 解析loader.path中相对路径的基础路径,通常是类路径位置。
  3. loader.args: 设置main方法的默认参数,以空格分隔。
  4. loader.main: 指定要启动的主类的名称,例如com.xxx.Application。
  5. loader.config.name: 指定属性文件的路径,例如classpath:loader.properties。
  6. loader.system: 一个布尔值标志,指示是否将所有属性添加到系统属性,默认为false。

附 pom.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.artisan</groupId>
    <artifactId>thinBootJar</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>thinBootJar</name>
    <description>thinBootJar</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>artisan-test-thin-boot-jar</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 用来配置可执行jar包中Main-Class的类型,这里一定要设置为 ZIP,使打的jar包中的Main-Class为PropertiesLauncher
 -->
                    <layout>ZIP</layout>
                    <includes>
                        <!-- 不打依赖包 -->
                        <include>
                            <!-- nothing 代表不存在的依赖包,意思就是什么依赖包都不引入-->
                            <groupId>nothing</groupId>
                            <artifactId>nothing</artifactId>
                        </include>
                        <!--                        <include>-->
                        <!-- common是引入的公共服务模块 -->
                        <!--                            <groupId>com.xxx.xx.rpc</groupId>-->
                        <!--                            <artifactId>common</artifactId>-->
                        <!--                        </include>-->
                    </includes>
                </configuration>
            </plugin>

            <!-- 将依赖的jar包copy到lib目录下  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <!-- 指定依赖的路径 -->
                            <outputDirectory>
                                ${project.build.directory}/lib
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Fat Jar
  • 瘦身
    • pom修改
      • copy lib
        • 启动 -Dloader.path
          • 验证
            • spring-boot-loader 依赖
              • 类继承关系
                • PropertiesLauncher属性配置
                • 附 pom.xml
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档