远方蔚蓝
一刹那情真,相逢不如不见

文章数量 126

访问次数 199827

运行天数 1437

最近活跃 2024-10-04 23:36:48

进入后台管理系统

类的加载器-实现动态加载jar包里的接口


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 202114日 下午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();
	}
}