Classloader

public class ServiceClassloader extends URLClassLoader {

    private static final ConcurrentHashMap<String, Class<?>> classCacheMap = new ConcurrentHashMap<String, Class<?>>();

    private final URL[] urls;

    public ServiceClassloader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
        this.urls = urls;
        init();
    }

    private void init() {
        for (URL url : urls) {
            initClassName(url);
        }
    }

    private void initClassName(URL url) {
        String path = url.getPath();
        try {
            JarFile jarFile = new JarFile(path);
            Enumeration<JarEntry> entries = jarFile.entries();
            while(entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String classFileName = entry.getName();
                if (classFileName.endsWith(".class")) {
                    classFileName = classFileName.replace("/", ".");
                    String className = classFileName.substring(0, classFileName.lastIndexOf("."));
                    loadClass(className);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        Class<?> clazz = classCacheMap.get(name);
        if (clazz == null) {
            clazz = super.loadClass(name);
            classCacheMap.put(name, clazz);
        }
        return clazz;
    }
}

 

public class SpringClassLoader extends ClassLoader {

    private ServiceClassloader serviceClassloader;

    public ServiceClassloader getServiceClassLoader() {
        return serviceClassloader;
    }

    public void setServiceClassLoader(ServiceClassloader serviceClassLoader) {
        this.serviceClassloader = serviceClassLoader;
    }

    /**
     * 定義加載器的加載規則
     * 1)先從SystemClassLoader進行加載指定的名字的class
     * 2)未找到,則用自定義的ServiceClassLoader加載指定路徑下的jar中的class
     * @param name  預加載的class名稱
     * @return 加載完的Class
     * @throws ClassNotFoundException
     */
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // first load classPath, then load third Libs;
        try {
            Class<?> clazz = loadClasspathClass(name);
            if (clazz != null) {
                return clazz;
            }
            clazz = loadThirdLibsClass(name);
            if (clazz != null) {
                return clazz;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new ClassNotFoundException(name);
    }

    /**
     * 經過SystemClassLoader進行加載指定名字的class
     * @param name
     * @return
     */
    private Class<?> loadClasspathClass(String name) {
        try {
            return super.loadClass(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 經過自定義的ServiceClassLoader加載系統路徑上jar文件指定名字class
     * @param name
     * @return
     */
    private Class<?> loadThirdLibsClass(String name) {
        try {
            return serviceClassloader.loadClass(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
相關文章
相關標籤/搜索