场景
Q:线上环境部署的项目中,需要用到随时可能变更的验证/加解密方法,但是又不能每次变更都硬编码然后重新线上部署!怎么能在不重新部署线上环境的情况下,变更验证/加解密方法呢? A:可以使用下面的动态加载外部jar并执行方法
实现逻辑
每次变更验证方法时,都让客户自己提供一个变更后的jar包,甲乙2方约定jar包中验证方法的类/方法/入参/出参,再通过页面上传的形式,上传jar包,后台通过反射的形式调用更新的jar包方法,达到动态更新线上环境验证方法的需求。
代码
测试jar包类
package test;
public class Verify{
public String verify(String name) {
//业务逻辑省略
return ”success“;
}
}
调用外部jar包
本地测试
public class LoadJar {
public static void main(String[] args) {
File file = new File("E:\\project\\main\\out\\artifacts\\main_jar\\main.jar");
try {
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:" + file.getAbsolutePath())});
Class<?> aClass = urlClassLoader.loadClass("test.Verify");
Object instance = aClass.newInstance();
Method method = aClass.getMethod("verify", String.class);
String result = (String) method.invoke(instance, "程序员");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
页面传参
public Double dynamicLoad(MultipartFile file) throws IOException {
//上传文件不能为空
if (file == null) {
throw new CustomException("动态计算lib库不能为空");
}
//这就是一个封装的文件上传返回文件路径的方法
String textUrl = FileUtil.uploadText(file);
//jar文件
File fileJar = new File(textUrl);
URLClassLoader urlClassLoader = null;
Class<?> mytest = null;
String substring = null;
if (file.getOriginalFilename() != null) {
substring = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
}
//jar包校验
if (!"jar".equals(substring)) {
throw new CustomException("只能上传“.jar”文件");
}
try {
//通过URLClassLoader加载外部jar
urlClassLoader = new URLClassLoader(new URL[]{new URL("file:" + fileJar.getAbsolutePath())});
//获取外部jar里面的具体类对象
mytest = urlClassLoader.loadClass("test.xxx");
//创建对象实例
Object instance = mytest.newInstance();
//获取实例当中的方法名为calculate,参数只有一个且类型为String的public方法
Method method = mytest.getMethod("calculate", String.class);
//传入实例以及方法参数信息执行这个方法
String result= (String) method.invoke(instance, "xxxxxxxxxxxxxxxx");
} catch (Exception e) {
throw new CustomException("计算出错,请导入正确动态计算库");
} finally {
//卸载关闭外部jar
try {
urlClassLoader.close();
} catch (IOException e) {
System.out.println("关闭外部jar失败:" + e.getMessage());
}
}
}
|