自定义类加载器

类加载器public abstract class ClassLoader 解说:它是抽象类,不能直接用。可使用其子类如urlclassloader。

其有两个重要方法:

loadclass类加载顺序

    protected synchronized Class<?> loadClass(String name, boolean resolve)
	throws ClassNotFoundException
    {
	// First, check if the class has already been loaded
	Class c = findLoadedClass(name);
	if (c == null) {
	    try {
		if (parent != null) {
		    c = parent.loadClass(name, false);
		} else {
		    c = findBootstrapClass0(name);
		}
	    } catch (ClassNotFoundException e) {
	        // If still not found, then invoke findClass in order
	        // to find the class.
	        c = findClass(name);
	    }
	}
	if (resolve) {
	    resolveClass(c);
	}
	return c;
    }

 findClass需要子类实现:用于加载具体的类,如类路径等

    protected Class<?> findClass(String name) throws ClassNotFoundException {
	throw new ClassNotFoundException(name);
    }

 

 

一、 URLClassLoader cl1=new URLClassLoader(urls, null); 说明?自定义ClassLoader可以使用现成的URLClassLoader指定parent为null,

new URLClassLoader(urls, null) =》

URLClassLoader的super(parent);=》

SecureClassLoader的super(parent);=》

ClassLoader的this.parent = parent;

所以最后会将ClassLoader的parent为null。

所以加载器还是会先从bootStrap中加载类。但不会从ext、app中加载。见以上第9

另外即使不赋为null,那parent->parent->....最后一定会有一个为null,即还是会执行到9行

这样好处是:自己写的类加载器不会将JRE的核心类覆盖掉。

 

二、 自定义ClassLoader可以使用现成的URLClassLoader且可以指定parent为null,为什么有时还要自己写呢?

虽然可以复用URLClassLoader,但其还是使用classloader的loadClass方法,即流程没变,如果要改变类加载顺序必须重写。

场景一:

应用的ClassLoader里面加载了1,2,3,4,5个JAR包。

自己的ClassLoader想共享应用的1,2,3,4的JAR包,但不想用5的JAR,这时要自己要在里面排除5,可根据包名。

场景二:

1.当系统要集成两个开源框架,而这两个框架使用了POI的两个版本的包、2.或者将新框架集成到现有系统时,有包版本冲突

这时可写自己的类加载器,分别加载不同的版本包 

你可能感兴趣的:(类加载器)