java 动态加载_Java如何在运行时动态加载Jar

本文介绍如何在Java运行时动态加载Jar包,通过一个实例展示具体步骤,并探讨ClassLoader的工作原理,特别是URLClassLoader在动态加载中的作用。文章详细讲解了动态加载Jar的实现过程,包括设置addURL方法可访问、获取系统类加载器、添加Jar路径到系统类路径,以及通过反射调用加载的类方法。
摘要由CSDN通过智能技术生成

导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景。如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用。下面将举一个简单实现Java动态加载Jar的例子。环境准备

动态加载Jar实现

解析与拓展

环境准备

为了便于实现Demo,这里构建一个模块化Maven项目dynamicloading,项目包含:dyna-loading-function方法库模块、dyna-loading-core核心模块。

e95caf668ffbaad05121dceed0927808.png

在dyna-loading-function中编写方法

编写一个方法抽象类,及一个实现类Split,class/**

* 方法抽象类

*/

public abstract class AbstractFunction {

public abstract void eval(String s);

}

/**

* 字符串截取方法

*/

public class Split extends AbstractFunction {

@Override

public void eval(String s) {

System.out.println("对字符串"+s+"进行截取操作");

}

}

将dyna-loading-function打成Jar包

093f1c53289d82718f6456d1ee1ef3a9.png

在dyna-loading-core模块实现动态加载Jarimport java.io.File;

import java.lang.reflect.Method;

import java.net.URL;

import java.net.URLClassLoader;

public class dynaLoadTest {

public static void main(String[] args) throws Exception{

//jar所在路径

String jarPath = "C:\\repo\\com\\wxb\\dyna-loading-function\\1.0-SNAPSHOT\\dyna-loading-function-1.0-SNAPSHOT.jar";

loadJar(jarPath);

//利用反射

Class> aClass = Class.forName("function.Split");

Object instance = aClass.newInstance();

//调用方法

aClass.getDeclaredMethod("eval", String.class).invoke(instance,

"hello word");

}

//动态加载Jar

public static void loadJar(String jarPath) {

File jarFile = new File(jarPath);

//文件存在

if (jarFile.exists() == false) {

System.out.println("jar file not found.");

return;

}

//从URLClassLoader类加载器中获取类的addURL方法

Method method = null;

try {

method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);

} catch (NoSuchMethodException | SecurityException e1) {

e1.printStackTrace();

}

// 获取方法的访问权限

boolean accessible = method.isAccessible();

try {

//修改访问权限为可写

if (accessible == false) {

method.setAccessible(true);

}

// 获取系统类加载器

URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

//获取jar文件的url路径

URL url = jarFile.toURI().toURL();

//jar路径加入到系统url路径里

method.invoke(classLoader, url);

} catch (Exception e) {

e.printStackTrace();

} finally {

method.setAccessible(accessible);

}

}

}

运行

ee783914a4eba776fd3e33e9701c64a3.png

解析与拓展

ClassLoader是类加载器,其具体作用就是将class文件加载到jvm虚拟机中去,程序就可以正确运行了。java程序运行的时候,类必须被加载到jvm虚拟机中才可以正常使用。但不是所有的class文件都在启动的时候全部加载,根据资料java最早就是为嵌入式系统而设计的,内存宝贵。如果开始时就把所有类都加载到jvm中,有些class可能在整个运行过程中都不会被用到,这样便会占用宝贵的内存。因此启动时会先把保证程序运行的基础类一次性加载到jvm中,其它class等到jvm用到的时候再通过动态加载将其加载到jvm虚拟中。

18fc95186819146e69e6361a28896fe5.png

Java中内置了很多的类加载器,而ClassLoader是所有类加载器的基类,它是个抽象类,其定义了类加载最核心的操作。因本文主题是动态加载Jar,所以下面我们主要讨论URLClassLoader。

fdb39d6ca85d0fe5e92bcf9e11ccce1b.png

URLClassLoader

URLClassLoader继承自SecureClassLoader,支持从jar文件和文件夹中获取class。而SecureClassLoader继承于ClassLoader。

核心代码://1、通过getDeclaredMethod获取URLClassLoader的addURL,这一步的目的是为了设置addURL方法可写

Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);

method.setAccessible(true);

//2、获取 URLClassLoader加载器

URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

//3、获取目标jar的URL

URL url = jarFile.toURI().toURL();

//4、执行addURL方法,通过URLclassLoader从指定jar中获取class并动态加到jvm虚拟机里

method.invoke(classLoader, url);

//5、class成功被动态加载进虚拟机后,就可以利用反射获取

Class> aClass = Class.forName("function.Split");

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值