第二篇博文主要讲解了ClassLoader的一些原理性的东西,本篇主要分析一些实战性的东西. 一般 获取ClassLoader会有如下三种方式:
1.this.getClass().getClassLoader(); 2.ClassLoader.getSystemClassLoader(); 3.Thread.currentThread().getContextClassLoader();
第二种方法通过ClassLoader类的静态方法getSystemClassLoader()获取,该方法返回就是AppClassLoader(个人觉得),
第三种方法通过当前线程获取,如果启动该线程的类在classPath下,获取到的自然就是AppClassLoader,如果启动线程的类在java.ext.dir目录下,获取到的就是extClassLoader,除了获取ClassLoader,第三种方式也可set ClassLoader,看代码,
class MyClassLoader extends URLClassLoader { MyClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } public static void main(String args[]) throws Exception{ File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin"); URL url=file.toURL(); URL urls[]=new URL[]{url}; MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(classLoader); Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest"); System.out.println(Thread.currentThread().getContextClassLoader()); } }
自定义了一个ClassLoader,指定加载目录,指定父加载器, 指定加载目录url2肯定不是当前项目(既MyClassLoader这个类所属项目)的目录,因为当前项目ClassPath下面的文件肯定会被appClassLoader这个父加载器先加载.
接下来说说自定义ClassLoader,上代码先,
代码1:
class MyClassLoader extends URLClassLoader { MyClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } public static void main(String args[]) throws Exception{ File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin"); URL url=file.toURL(); URL urls[]=new URL[]{url}; MyClassLoader classLoader=new MyClassLoader(urls,ClassLoader.getSystemClassLoader()); Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest"); Object object=newClass.newInstance(); Method method=newClass.getMethod("setName",String.class); method.invoke(object, "jake"); Method method2=newClass.getMethod("sayName"); method2.invoke(object); classLoader.close(); } }代码2:
class MyClassLoader2 extends ClassLoader { MyClassLoader2(ClassLoader parent) { super(parent); } public Class<?> findClass(String name) { //ps: 该方法实现还是有问题的 FileInputStream input=null; ByteOutputStream out=null; String oName=name; try { name=name.replace(".", File.separator).concat(".class"); File file=new File("D:\\wp\\JFinalWp\\ClassLoader\\bin\\"+name); input=new FileInputStream(file); out=new ByteOutputStream(); byte by[]=new byte[1024]; int len=0; while((len=input.read(by))!=-1){ out.write(by, 0, len); } byte bt[]=out.getBytes(); return defineClass(oName,bt, 0, bt.length); } catch (Exception e) { e.printStackTrace(); }finally{ if(input!=null){ try { input.close(); } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ out.close(); } } return null; } public static void main(String args[]) throws Exception{ MyClassLoader2 classLoader=new MyClassLoader2(ClassLoader.getSystemClassLoader()); Class newClass=classLoader.findClass("com.my.classloader.MyClassLoaderTest"); Object object=newClass.newInstance(); Method method=newClass.getMethod("setName",String.class); method.invoke(object, "jake"); Method method2=newClass.getMethod("sayName"); method2.invoke(object); } }
代码二是通过继承ClassLoader这个顶层类加载器实现,findClass(String name) 这个方法需要自己实现,比较麻烦,上面代码二的方法还是有点问题的,
一般通过代码一的方式实现就行了,URLClassLoader内部实现还是完善的.