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;
    }
}
相关推荐
算.子1 分钟前
【Spring AI 实战】五、RAG 核心原理:为什么需要检索增强生成?
java·人工智能·spring
阿正的梦工坊4 分钟前
JavaScript 闭包:从入门到精通
开发语言·javascript·ecmascript
qq_12084093715 分钟前
Three.js 性能实战:大场景从 15FPS 到 60FPS 的工程化优化路径
开发语言·前端·javascript
XS0301068 分钟前
Java基础笔记(一)
java·笔记·python
程序员老邢11 分钟前
【产品底稿 05】商助慧 V1.1 里程碑:RAG 文章仿写模块全链路实现
java·spring boot·程序人生·ai·milvus
小张同学82417 分钟前
[特殊字符]Python 进阶实战指南(PyCharm 专属优化):从高效编码到工程化落地,告别新手低效写法
开发语言·python·pycharm
lly20240625 分钟前
PHP Math
开发语言
消失的旧时光-194329 分钟前
Spring Boot 实战(三):Service 分层 + 统一返回 + 异常处理(工程级写法)
java·spring boot·接口·解耦
云烟成雨TD30 分钟前
Spring AI Alibaba 1.x 系列【20】MessagesAgentHook 、MessagesModelHook 相关实现类
java·人工智能·spring
霸道流氓气质31 分钟前
SpringBoot中集成LangChain4j实现集成阿里百炼平台进行AI对话记忆功能和对话隔离功能
java·人工智能·spring boot·langchain4j