java classloader 分级加载jar

    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成为并行加载器。

猜你喜欢

转载自j-sun.iteye.com/blog/2393690