java classloader 分级加载 样例。
CustomClassder 作为 app jar包得加载器, 开启了 并行加载选项。
package com.jsun; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; /** * 自定义classloader */ public class CustomClassder extends URLClassLoader { public CustomClassder(URL[] urls, ClassLoader parent) { super(urls, parent); } public static void register (){ try{ final Method registerParallel = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable"); registerParallel.setAccessible(true); registerParallel.invoke(null); }catch (Exception e){ e.printStackTrace(); } } }
CustomClassder 继承 URLClassLoader , 因此只要再构造函数传入 需要加载得appjar地址就行, 然后第二个参数是 当前线程得classloader,当前为 appclassloader
package com.jsun; import java.io.File; import java.lang.reflect.Method; import java.net.URL; public class test { public static void main(String[] arg)throws Exception{ String jar = "G:\\workspace\\myclassloader\\outjar\\test.jar"; File file = new File(jar); URL url = file.toURI().toURL(); CustomClassder.register(); CustomClassder classder = new CustomClassder(new URL[]{url},Thread.currentThread().getContextClassLoader()); Thread thread = new Thread(new Runnable() { @Override public void run() { runApp(); } }); thread.setContextClassLoader(classder); thread.start(); } public static void runApp (){ try { Class appstartClass = Thread.currentThread().getContextClassLoader().loadClass("com.TestBean"); Object app = appstartClass.newInstance(); Method method = appstartClass.getMethod("appStartRun"); String appRunResult = (String) method.invoke(app,null); System.out.println(appRunResult); } catch (Exception e) { e.printStackTrace(); } } }
CustomClassder.register() 把CustomClassder 注册到并行单粒类ParallelLoaders中,调用
CustomClassder.register() 时当前是 appclassloader, 然后利用 appclassloader得实例 对ParallelLoaders
进行 CustomClassder得注册。 所以当新建 CustomClassder时
private ClassLoader(Void unused, ClassLoader parent) { this.parent = parent; if (ParallelLoaders.isRegistered(this.getClass())) { parallelLockMap = new ConcurrentHashMap<>(); package2certs = new ConcurrentHashMap<>(); domains = Collections.synchronizedSet(new HashSet<ProtectionDomain>()); assertionLock = new Object(); } else { // no finer-grained lock; lock on the classloader instance parallelLockMap = null; package2certs = new Hashtable<>(); domains = new HashSet<>(); assertionLock = this; } }
Classloader中得 ParallelLoaders.isRegistered 便能获取到 CustomClassder.class 因此 CustomClassder成为并行加载器。