Java动态执行jar包中类的方法

动态加载执行jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行。

结论

通过反射可以实现动态调用jar包中的类的方法

环境

jdk8

Springboot 2.7.14

测试环境介绍

新建一个SpringBoot项目,提供Controller的两个访问接口;m1接口调用jar包中的TestClass的m1方法;m2接口调用jar包中的TestClass的m2方法;

TestJar的包名:test.jar

TestJar下的测试类:TestClass

方法1:m1

方法2:m2(带参数)

测试步骤

  1. 将TestJar打成jar包

  2. 将TestJar-1.0-SNAPSHOT.jar放在待测试的SpringBoot项目的resource/lib下

  3. 启动SpringBoot项目,访问接口m1、m2

关键代码

TestController.java

java 复制代码
package cn.only.hww.test.controller;

import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;

/**
 * author       : Wayne Hu
 * date created : Created in 2024/7/8 11:32
 * description  :
 * class name   : TestController
 */
@RestController
@RequestMapping("test")
public class TestController {
    // 从resources目录加载jar文件
    ClassPathResource resource = new ClassPathResource("lib/TestJar-1.0-SNAPSHOT.jar");
    File jarFile = new File(System.getProperty("java.io.tmpdir") + "/TestJar-1.0-SNAPSHOT.jar");



    @GetMapping("m1")
    public String test1() {
        String result = null;
        try {

            // 创建URLClassLoader加载jar包
            URL jarUrl = jarFile.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, TestController.class.getClassLoader());

            // 加载类并调用方法
            Class<?> testClass = classLoader.loadClass("test.jar.TestClass");
            Object testClassInstance = testClass.getDeclaredConstructor().newInstance();
            FileCopyUtils.copy(resource.getInputStream(), Files.newOutputStream(jarFile.toPath()));

            Method m1Method = testClass.getMethod("m1");
            result = (String) m1Method.invoke(testClassInstance);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "test1 result: " + result;
    }

    @GetMapping("m2")
    public String test2() {
        String result = null;
        try {
            FileCopyUtils.copy(resource.getInputStream(), Files.newOutputStream(jarFile.toPath()));

            // 创建URLClassLoader加载jar包
            URL jarUrl = jarFile.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, TestController.class.getClassLoader());

            // 加载类并调用方法
            Class<?> testClass = classLoader.loadClass("test.jar.TestClass");
            Object testClassInstance = testClass.getDeclaredConstructor().newInstance();
            Method m1Method = testClass.getMethod("m2", String.class);
            String param = "{'user':'admin'}";
            result = (String) m1Method.invoke(testClassInstance, param);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "test1 result: " + result;
    }
}

TestClass.java

java 复制代码
package test.jar;

/**
 * author       : Wayne Hu
 * date created : Created in 2024/7/8 11:37
 * description  :
 * class name   : TestClass
 */
public class TestClass {
    public String m1(){
        System.out.println("执行jar包方法1");
        return "我是来自jar包的m1方法的返回数据";
    }

    public String m2(String data){
        System.out.println("执行jar包方法2,参数为:" + data);
        return "我是来自jar包的m2方法的返回数据,参数为:" + data;
    }
}
相关推荐
唐青枫11 小时前
Java JDBC 实战指南:从 Connection 到事务和连接池
java
一个做软件开发的牛马12 小时前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
用户37215742613512 小时前
Java 处理 PDF 图片:提取 PDF 中的图片,并压缩 PDF 图片体积
java
用户37215742613512 小时前
Java 打印 Word 文档:从基础打印到高级设置
java
用户3521802454751 天前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
东坡白菜1 天前
破局全栈:一个前端开发的Java入门实战记录(1)
java·全栈
唐青枫1 天前
Java Tomcat 实战指南:从 Servlet 容器到 Spring Boot 部署
java
wsaaaqqq1 天前
roudan:自由选择实体、灵活操作数据、快速写入数据库的 Java 框架
java
plainGeekDev1 天前
null 判断 → Kotlin 可空类型
android·java·kotlin
糖拌西瓜皮1 天前
Java开发者视角:深入理解Node.js异步编程模型
java·后端·node.js