SpringBoot加载外部Jar实现功能按需扩展

 更新时间:2025年06月17日 10:20:48   作者:皮皮林551  
这篇文章主要为大家详细介绍了SpringBoot加载外部Jar实现功能按需扩展的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

实现方案

实现这个很简单,只需要完成下面两步:

  • 想办法将 Class 加载到 JVM
  • 使 Spring 扫描到 Class

有时候java中的各种框架以及复杂的概念源码给我们造成了很大理解障碍,特别是Spring家族的所以先想清楚大致实现步骤比较好

将Class加载到JVM

现在我们设定需要加载的 Jar 在 /user/local/java/plugins 目录下,对于第 1 步,现在有如下几种实现方式:

  • 扩大 -cp 由 AppClassLoader 帮我们加载外部 Jar
  • 使用 SpringBoot 提供的启动参数 loader.path 实现
  • 自定义 classloader 实现加载指定位置的 Jar

其中 1 和 3 是JDK提供的方案,2是 SpringBoot 扩展的方案,毕竟 SpringBoot 也需要自定义加载很多类顺带扩展了一个参数出来

方案1

扩大 -cp 由 AppClassLoader 帮我们加载外部 Jar

可以使用 classpath 指定类加载的路径,但 classpath 的生效是有条件的,这里其实对应了 Jar 包的两种启动方式:通过Jar包里的Main函数启动或者运行Jar启动

SpringBoot 打包后 MANIFEST.MF 内容如下:

Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 18
Implementation-Title: intelligent-soul
Implementation-Version: 0.0.1-SNAPSHOT
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.test.MyApplication
Spring-Boot-Version: 2.6.15
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

所以需要使用 Main 函数启动的方式,不能使用之前的常用的 Jar 包启动方式了。对于 SpringBoot 应用 Main-Class 是 JarLauncher 所以此时启动命令要改成

java  -cp  /user/local/java/plugins org.springframework.boot.loader.JarLauncher
  • 优点:实现简单
  • 缺点:每个 Jar 包启动命令都一样了,不好区分

方案2

使用SpringBoot扩展的启动参数,使用java -jar 配合Loader.path参数

因为 Spring Boot 程序大多是打成 Jar 包,使用 java -jar boot.jar 的方式启动 (此时 -cp 无效),可以使用 loader.path 指定类加载路径加载其他 Jar,但 loader.path 生效也是有条件的:

SpringBoot 默认打包方式的Main-ClassJarLauncher

配置 Main-Class

为了使 loader.path 参数生效需要生成 Jar 包的 Main-Class 项配置为 PropertiesLauncher,在 maven 中如下配置,可参考 Using the PropertiesLauncher:

<build>
     <plugins>
         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
             <configuration>
                 <!-- 打包时排除scope为system的包 -->
                 <includeSystemScope>false</includeSystemScope>
                 <!-- jvm启动时通过-Dloader.path加载包,必须指定layout为ZIP,否则-Dloader.path无效!!! -->
                 <layout>ZIP</layout>
             </configuration>
             <executions>
                 <execution>
                     <goals>
                         <goal>repackage</goal>
                     </goals>
                 </execution>
             </executions>
         </plugin>
     </plugins>
     <finalName>Test</finalName>
</build>

其中 layout 可配置值如下:

1、JAR,即通常的可执行 jar

Main-Class: org.springframework.boot.loader.JarLauncher

2、WAR,即通常的可执行war,需要的 servlet 容器依赖位于 WEB-INF/lib-provided

Main-Class: org.springframework.boot.loader.WarLauncher

3、ZIP,即DIR,类似于 JAR

Main-Class: org.springframework.boot.loader.PropertiesLauncher

4、MODULE,将所有的依赖库打包(scopeprovided的除外),但是不打包 Spring Boot 的任何Launcher

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

无论启动类是 JarLauncher 或者 PropertiesLauncherloader.path 引入的 Jar 和 Spring Boot jar 包中 BOOT-INFO/lib 包下 Jar 都是使用类加载器 org.springframework.boot.loader.LaunchedURLClassLoader 进行加载,也就是说他们使用的是同一个类加载器。这个类加载器主要就是负责加载 Jar 包里的 Jar 的加载,因为JDK没有实现该功能所以 SpringBoot 定义了该类

注意到同一个程序,打包成不同类型时,PropertiesLauncher (20s) 比 JarLauncher (8s) 启动慢很多。

方案3

自定义类加载器,加载固定目录下的jar包或者读取环境变量路径

这种方式需要程序启动的某个节点,调用自定义类加载器去加载指定目录下的 Jar 包,时间点不是很好控制。但这个定制化程度比较高。

//可以在这里调用自定义类加载
SpringApplication.run(SpringBootDemo.class, args);

方案4

通过设置-Xbootclasspath/a或者 Extention ClassLoader通过改变参数java.ext.dirs实现

会改变系统类加载器加载行为不安全不推荐!!!

加载后的类如何扫描进入Spring容器

对于业务 Jar 包类,可以预先在SpringBoot中指定好扫描包路径,那么只需要插件包路径是com.demo开头即可,如下

@SpringBootApplication(scanBasePackages = {"com.demo"})
public class SpringBootDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }

如不符合包名前缀一致的情况,需要在jar包META-INF下的spring.factories指定好自动装配的类即可如 mybatis-plus:

# Auto Configure
org.springframework.boot.env.EnvironmentPostProcessor=\
  com.baomidou.mybatisplus.autoconfigure.SafetyEncryptProcessor
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.baomidou.mybatisplus.autoconfigure.IdentifierGeneratorAutoConfiguration,\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

到此这篇关于SpringBoot加载外部Jar实现功能按需扩展的文章就介绍到这了,更多相关SpringBoot加载外部Jar内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot如何使用httpcomponents实现http请求

    Spring Boot如何使用httpcomponents实现http请求

    这篇文章主要介绍了Spring Boot使用httpcomponents实现http请求的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Spring配置文件和mybatis详解

    Spring配置文件和mybatis详解

    MyBatis是一款优秀的持久层框架,支持自定义SQL、存储过程、高级映射以及多种配置方式,本文给大家介绍Spring配置文件和mybatis的相关知识,感兴趣的朋友跟随小编一起看看吧
    2025-10-10
  • java 实现下压栈的操作(能动态调整数组大小)

    java 实现下压栈的操作(能动态调整数组大小)

    这篇文章主要介绍了java 实现下压栈的操作(能动态调整数组大小),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java线程本地变量导致的缓存问题解决方法

    Java线程本地变量导致的缓存问题解决方法

    使用缓存可以缓解大流量压力,显著提高程序的性能,我们在使用缓存系统时,尤其是大并发情况下,经常会遇到一些疑难杂症,这篇文章主要给大家介绍了关于Java线程本地变量导致的缓存问题的解决方法,需要的朋友可以参考下,
    2024-08-08
  • 手写简版kedis分布式key及value服务的实现及配置

    手写简版kedis分布式key及value服务的实现及配置

    这篇文章主要为大家介绍了手写简版的kedis分布式key及value服务的实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • Java代码注释规范详解

    Java代码注释规范详解

    代码附有注释对程序开发者来说非常重要,随着技术的发展,在项目开发过程中,必须要求程序员写好代码注释,这样有利于代码后续的编写和使用。下面给大家分享java代码注释的规范,需要的朋友参考下
    2016-02-02
  • Java中callable的实现原理

    Java中callable的实现原理

    本文主要介绍了Java里的callable的实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • Spring boot项目redisTemplate实现轻量级消息队列的方法

    Spring boot项目redisTemplate实现轻量级消息队列的方法

    这篇文章主要给大家介绍了关于Spring boot项目redisTemplate实现轻量级消息队列的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • SpringBoot使用Kaptcha实现验证码的生成与验证功能

    SpringBoot使用Kaptcha实现验证码的生成与验证功能

    这篇文章主要介绍了SpringBoot使用Kaptcha实现验证码的生成与验证功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Java实现将word转换为html的方法示例【doc与docx格式】

    Java实现将word转换为html的方法示例【doc与docx格式】

    这篇文章主要介绍了Java实现将word转换为html的方法,结合实例形式分析了java针对doc与docx格式文件的相关转换操作技巧,需要的朋友可以参考下
    2019-03-03

最新评论