网站首页 > java教程 正文
导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景。如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用。下面将举一个简单实现Java动态加载Jar的例子。
- 环境准备
- 动态加载Jar实现
- 解析与拓展
环境准备
为了便于实现Demo,这里构建一个模块化Maven项目dynamicloading,项目包含:dyna-loading-function方法库模块、dyna-loading-core核心模块。
在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包
在dyna-loading-core模块实现动态加载Jar
import 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);
}
}
}
运行
解析与拓展
ClassLoader是类加载器,其具体作用就是将class文件加载到jvm虚拟机中去,程序就可以正确运行了。java程序运行的时候,类必须被加载到jvm虚拟机中才可以正常使用。但不是所有的class文件都在启动的时候全部加载,根据资料java最早就是为嵌入式系统而设计的,内存宝贵。如果开始时就把所有类都加载到jvm中,有些class可能在整个运行过程中都不会被用到,这样便会占用宝贵的内存。因此启动时会先把保证程序运行的基础类一次性加载到jvm中,其它class等到jvm用到的时候再通过动态加载将其加载到jvm虚拟中。
Java中内置了很多的类加载器,而ClassLoader是所有类加载器的基类,它是个抽象类,其定义了类加载最核心的操作。因本文主题是动态加载Jar,所以下面我们主要讨论URLClassLoader。
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");
最后
感谢您的阅读,如果喜欢本文欢迎关注和转发,本头条号将坚持原创,持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步
猜你喜欢
- 2024-10-01 Java中String类字符串拼接谁的效率最低
- 2024-10-01 100个Java工具类之2:字符串之多种个性化格式处理
- 2024-10-01 每天积累一点点(Java基础——》String类学习——one day)
- 2024-10-01 Java中如何使用正则技术提取html中的任意内容
- 2024-10-01 Java String 常用方法,涵盖全部(java string的用法)
- 2024-10-01 在Java中将String转换为char(java string转换char)
- 2024-10-01 「JavaWeb基础」文件上传和下载(修订版)
- 2024-10-01 浅谈Java中字符串的初始化及字符串操作类
- 2024-10-01 MySql字符串拆分实现split功能(字段分割转列、转行)
- 2024-10-01 Java,FreeMarker,模板引擎,通过案例代码,学懂模板引擎
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)