1、需求
需要在系统中上传一个jar包到服务器中,需要在不重启服务器的前提下加载这个jar包中的接口方法
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* 类加载器工具,调用本地上传到服务器指定目录的jar包里封装的方法,不需要启动服务器
* @author wst 2021年1月4日 下午1:37:36
*
*/
public class ClassLoaderUtils extends URLClassLoader {
private static boolean canCloseJar = false;
private List<JarURLConnection> cachedJarFiles;
static {
// 1.7之后可以直接调用close方法关闭打开的jar,需要判断当前运行的环境是否支持close方法,如果不支持,需要缓存,避免卸载模块后无法删除jar
try {
URLClassLoader.class.getMethod("close");
canCloseJar = true;
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
public ClassLoaderUtils(URL[] urls, ClassLoader parent) {
super(new URL[] {}, parent);
init(urls);
}
public ClassLoaderUtils(URL[] urls) {
super(new URL[] {});
init(urls);
}
public ClassLoaderUtils(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
super(new URL[] {}, parent, factory);
init(urls);
}
private void init(URL[] urls) {
cachedJarFiles = canCloseJar ? null : new ArrayList<JarURLConnection>();
if (urls != null) {
for (URL url : urls) {
this.addURL(url);
}
}
}
@Override
protected void addURL(URL url) {
if (!canCloseJar) {
try {
// 打开并缓存文件url连接
URLConnection uc = url.openConnection();
if (uc instanceof JarURLConnection) {
uc.setUseCaches(true);
((JarURLConnection) uc).getManifest();
cachedJarFiles.add((JarURLConnection) uc);
}
} catch (Exception e) {
}
}
super.addURL(url);
}
public void close() throws IOException {
if (canCloseJar) {
try {
super.close();
} catch (IOException ioe) {
}
} else {
for (JarURLConnection conn : cachedJarFiles) {
conn.getJarFile().close();
}
cachedJarFiles.clear();
}
}
public static void main(String[] args) throws Exception {
// 加载jar包
ClassLoaderUtils classload = new ClassLoaderUtils(new URL[] { new URL("file:D:\\loadResources.jar") });
// 使用反射的方式加载类
Class<?> MyTest = classload.loadClass("需要加载的类全名如: com.xx.xx.Class");
// 创建实例
Object instance = MyTest.newInstance();
// 找到需要执行的方法名称
Method method = MyTest.getMethod("方法", String.class);
// 执行方法
Object ada = method.invoke(instance, "传入参数");
System.out.println(ada);
// ada为执行方法返回的值
classload.close();
}
}