闲来无事,看源码的时候看到了这么一句:Thread.currentThread().getContextClassLoader()
觉得似懂非懂的,不就是类加载器吗!不就是线程上下文的类加载器吗!可是为什么要这么写呢?
于是乎百度之。。。找了半天也没有看到有人来解释下这个东东的。
然后搜索JDK的API发现java.lang.Thread不仅仅有getContextClassLoader而且还有setContextClassLoader,很明显这两个应该是互为补充的。
package classLoader; public class ClassLoaderTree { public static void main(String[] args) { //每个JAVA类都有一个指向它的类加载器的引用 ClassLoader classLoader = ClassLoaderTree.class.getClassLoader(); while (classLoader != null) { System.out.println(classLoader); classLoader = classLoader.getParent(); } } }
package classLoader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * 文件系统的类加载器 * 要实现自己的类加载器必须继承ClassLoader * 然后重写findClass方法,最后通过调用父类的defineClass方法把类给定义出来。 * * @author li * */ public class FileSystemClassLoader extends ClassLoader { private String rootDir; public FileSystemClassLoader(String rootDir) { super(); this.rootDir = rootDir; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] byteArray = getClassData(name); if (byteArray == null) { throw new ClassNotFoundException(name); } else { return defineClass(name, byteArray, 0, byteArray.length); } } private byte[] getClassData(String className) { String classPath = classNameToPath(className); byte[] buf = new byte[1024]; ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); InputStream in = null; try { in = new FileInputStream(classPath); while (in.read(buf) != -1) { byteArray.write(buf); } } catch (IOException e) { e.printStackTrace(); return null; } finally { if (in != null) try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return byteArray.toByteArray(); } private String classNameToPath(String className) { StringBuilder buff = new StringBuilder(); buff.append(rootDir).append(File.separatorChar) .append(className.replace('.', File.separatorChar)) .append(".class"); System.out.println(buff); return buff.toString(); } }
package classLoader; public class Sample { private Sample instance; public void setInstance(Object instance) { System.out.println("setInstance"); this.instance = (Sample) instance; } }
package classLoader; import java.lang.reflect.Method; public class Test { static Class<?> t1Clz = null; static Class<?> t2Clz = null; public static void main(String[] args) throws InterruptedException { String classDir = "D:\\eclipse\\myTest\\web\\WEB-INF\\classes\\classLoader"; /* * 两个类加载器分别去加载指定的类,但这个类只能被加载一次 */ FileSystemClassLoader fsc1 = new FileSystemClassLoader(classDir); FileSystemClassLoader fsc2 = new FileSystemClassLoader(classDir); final String className = "classLoader.Sample"; try { Class<?> class1 = fsc1.loadClass(className); Object obj1 = class1.newInstance(); Class<?> class2 = fsc2.loadClass(className); Object obj2 = class2.newInstance(); System.out.println(class1 == class2); System.out.println(obj1 == obj2); Method method1 = class1.getMethod("setInstance", java.lang.Object.class); System.out.println(method1); method1.invoke(obj1, obj2); } catch (Exception e) { e.printStackTrace(); } } }