使用URLClassLoader动态加载jar
2021-01-26 04:14
标签:param conf alt schedule stack path led mic img 背景介绍 现在有个场景,系统希望引入一些特殊的业务“函数”,并支持热更新。来看看我们是怎么实现的。 业务函数接口:IFunction.java 函数调用工具类:FunctionUtil.java 支持从jar读取的类加载器:JarURLClassLoader.java 将IFunction的实现分离,放在独立的工程内,如下图: Base64Encode.java 将BizFunction打包成jar,部署在可供访问的服务器上,如:http://192.168.1.1:8000/biz-functions-v1.0.jar 热更新的方式一般有2种: 1.定时刷新,如发现jar文件发生变化则重新加载; 2-动态触发,下发指定的更新动作进行重新加载; 方式1的简单实现 : >> OK, THIS IS IT! 使用URLClassLoader动态加载jar 标签:param conf alt schedule stack path led mic img 原文地址:https://www.cnblogs.com/lichmama/p/12858517.html在某些项目中会使用插件化技术实现一些动态“插拔”或热更新的功能。一般的做法是,定义一个标准接口,然后将实现分离进行独立部署或更新。
/** 业务函数接口 **/
public interface IFunction {
/** 函数名称 **/
public String getName();
/** 函数描述 **/
public String getDesc();
/** 函数运行异常时返回默认值 **/
public Object getDefVal();
/** 调用函数 **/
public Object process(Object... args) throws Exception;
/** 检查入参是否为空 **/
default boolean checkArgsIsEmpty(Object... args) {
System.out.println(">> args=" + Arrays.toString(args));
return args == null || args.length == 0;
}
}
public class FunctionUtil {
private static Map
public class JarURLClassLoader {
private URL jar;
private URLClassLoader classLoader;
public JarURLClassLoader(URL jar) {
this.jar = jar;
classLoader = new URLClassLoader(new URL[] { jar });
}
/**
* 在指定包路径下加载子类
*
* @param superClass
* @param pkgName
* @return
*/
public Set
public class Base64Encode implements IFunction {
@Override
public String getName() {
return "base64Encode";
}
@Override
public String getDesc() {
return "Base64加密";
}
@Override
public Object process(Object... args) {
if (checkArgsIsEmpty(args)) {
return "";
}
String s = (String) args[0];
return Base64.getEncoder().encodeToString(s.getBytes());
}
@Override
public Object getDefVal() {
return "";
}
}
@Configuration
@EnableScheduling
public class CronJob {
@Value("${function.jar.url}")
private String jarUrl;
/**
* 更新函数的定时任务
*/
@Scheduled(cron = "${function.update.cron}")
public void updateFunction() {
try {
UpdateFunction.updateIfModified(jarUrl);
} catch (Exception e) {
e.printStackTrace();
}
}
/** 更新函数的内部工具类 **/
private static class UpdateFunction extends FunctionUtil {
private static long lastModified = 0L;
private static void updateIfModified(String jarUrl) throws Exception {
URL jar = new URL(jarUrl);
long modified = jar.openConnection().getLastModified();
// 判断jar是否发生变化
if (lastModified == modified) {
return;
} else {
// 保存最新的修改时间
lastModified = modified;
}
Map functions = loadFunctions(jar);
resetFunctions(functions);
}
}
}
文章标题:使用URLClassLoader动态加载jar
文章链接:http://soscw.com/index.php/essay/47103.html