自定义ClassLoader的使用

 1 import java.io.ByteArrayOutputStream;
 2 import java.io.File;
 3 import java.io.FileInputStream;
 4 import java.io.InputStream;
 5 
 6 public class ClassLoaderTest extends ClassLoader {
 7 
 8     private String classLoaderName;
 9     private String fileExtension = ".class";
10 
11     /**
12      * 默认的情况下,自定义类的加载器会以SystemClassLoader为父类加载器,如果要改变这种机制,调第二种生成方法
13      */
14 
15     public ClassLoaderTest(String classLoaderName) {
16         super();
17         this.classLoaderName = classLoaderName;
18     }
19 
20     public ClassLoaderTest(ClassLoader classLoader, String classLoaderName) {
21         super(classLoader);
22         this.classLoaderName = classLoaderName;
23     }
24 
25     /**
26      * 该方法会在底层调用
27      */
28     @Override
29     protected Class<?> findClass(String className) throws ClassNotFoundException {
30         byte[] data = this.loadClassData(className);
31         return this.defineClass(className, data, 0, data.length);
32     }
33 
34     // 在该示例里,不会执行该方法,也就是说,由于双亲委托机制,会由应用类加载器加载
35     // 如果加载的类,不在classpath里,意思就是应用类加载器加载不了,才会由此加载器加载
36     private byte[] loadClassData(String name) {
37 
38         byte[] data = null;
39         InputStream is = null;
40         ByteArrayOutputStream baos = null;
41 
42         try {
43             this.classLoaderName = this.classLoaderName.replace(".", "/");
44 
45             is = new FileInputStream(new File(name + this.fileExtension));
46             baos = new ByteArrayOutputStream();
47 
48             int ch = 0;
49 
50             while (-1 != (ch = is.read())) {
51                 baos.write(ch);
52             }
53             data = baos.toByteArray();
54 
55         } catch (Exception e) {
56             e.printStackTrace();
57         } finally {
58             try {
59                 is.close();
60                 baos.close();
61             } catch (Exception e) {
62                 e.printStackTrace();
63             }
64         }
65 
66         return data;
67     }
68 
69     public static void test(ClassLoader classLoader) throws Exception {
70         Class<?> clazz = classLoader.loadClass("类名");
71         Object o = clazz.newInstance();
72         System.out.println(o);
73     }
74 
75     public static void main(String[] args) throws Exception {
76         ClassLoaderTest loader1 = new ClassLoaderTest("loader1");
77         test(loader1);
78     }
79 
80 }

 

 

 

ps:同一个加载器的命名空间里,同一个类只能被加载一次

命名空间:由所有的父加载器和自己加载器组成的空间

只有由自定义类加载器的类才能被卸载

 

posted @ 2018-05-10 17:26  无名草110  阅读(959)  评论(0编辑  收藏  举报