Java类加载器

类加载器层次结构(由高到低)
1.引导类加载器 bootstrap class loader
作用:用来加载java的核心库JAVA_HOME/jre/lib/rt.jar,不继承自java.lang.ClassLoader
2.扩展类加载器 extensions class loader
作用:Java虚拟机的实现回提供一个扩展目录,该类加载器在此目录里面查找并加载java类
3.应用程序类加载器 application class loader
作用:一般java应用类都是由它来完成
4.自定义类加载器
作用:实现自己的类加载器,以满足一些特殊要求
继承java.lang.ClassLoader类
  自定义文件加载器:

 1 import java.io.ByteArrayOutputStream;
 2 import java.io.FileInputStream;
 3 import java.io.FileNotFoundException;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 
 7 /**
 8  * 自定义文件类加载器
 9  * 1.继承java.lang.ClassLoader
10  * @author Nicotine
11  *
12  */
13 public class FileSystemClassLoader extends ClassLoader {
14     //com.sansan.test.User 在D:/test/读取 
15     //文件路径
16     private String rootDir;
17 
18     public FileSystemClassLoader(String rootDir) {
19         this.rootDir = rootDir;
20     }
21     @Override
22     protected Class<?> findClass(String name) throws ClassNotFoundException {
23     
24         Class<?> c = findLoadedClass(name);
25         
26         //先查看有没有加载过这个类,如果已经加载过了,则直接返回;如果没有,则加载新的类
27         if (null!=c) {
28             return c;
29         }else {
30             //双亲模式:获取父类加载器,
31             ClassLoader parent = this.getParent();
32             try {
33                 c = parent.getClass();
34             } catch (Exception e) {
35             }
36         }
37         if (null!=c) {
38             return c;
39         }else {
40             byte[] classData = getClassData(name);
41             if (null==classData) {
42                 throw new ClassNotFoundException();
43             }else{
44                 c=defineClass(name, classData, 0,classData.length);
45             }
46         }
47         return c;
48     }
49     private byte[] getClassData(String classname) {
50         //源数据路径
51         String path = rootDir + "/"+classname.replace(".","/")+".class";
52         //读取
53         //IOUtils,可以使用它将IO流的数据转换成字节数组
54         //选择流
55         InputStream is = null;
56         ByteArrayOutputStream baos = new ByteArrayOutputStream();
57         
58         try {
59             is=new  FileInputStream(path);
60             byte[] buffer = new byte[1024];
61             int temp = 0;
62             //读取
63             while ((temp=is.read(buffer))!= -1) {
64                 baos.write(buffer,0,temp);
65             }
66             return baos.toByteArray();
67         } catch (FileNotFoundException e) {
68             e.printStackTrace();
69             return null;
70         } catch (IOException e) {
71             e.printStackTrace();
72             return null;
73         }finally{
74             if (is!=null) {
75                 try {
76                     is.close();
77                 } catch (IOException e) {
78                     e.printStackTrace();
79                 }
80             }
81             if (baos!=null) {
82                 try {
83                     baos.close();
84                 } catch (IOException e) {
85                     e.printStackTrace();
86                 }
87             }
88         }
89     }
90 }

测试代码:

public class TestFileClass {
    public static void main(String[] args) throws ClassNotFoundException {
        FileSystemClassLoader loader = new FileSystemClassLoader("D:/test");
        Class<?> c = loader.loadClass("com.sansan.test.HelloWorld");
        System.out.println(c.hashCode());
    }
}

运行输出类的哈希值


java.lang.ClassLoader类
根据一个指定的类的名称,找到或者生成其对应的字节码,然后从这些字节码中定义一个java类,级java.lang.Class的一个实例
相关方法
getParent() 返回该类加载器的父类加载器
loadClass(String name) 加载名称为name的类,返回结果就是java.lang.Class类的实例
findClass(String name) 查找名称为name的类,返回结果就是java.lang.Class类的实例
findLoadedClass(String name) 查找名称为name的已经被加载过的类,返回结果就是java.lang.Class类的实例
defineClass(String name,byte[] b,int off,int len)把字节数组b中的内容转换成java类,返回结果就是java.lang.Class类的实例
resolveClass(Class<?> c)链接指定的Java类


一般采用代理模式
交给其它加载器来加载指定的类
双亲委托机制
父类加载器优先加载
为了保证java核心库的类型安全
这种机制就保证不会出现用户自己能定义java.lang.Object类的情况
双亲委托机制是代理模式的一种
并不是所有的类加载器都采用双亲委托机制
Tomcat服务器加载器也是用代理模式,所不同的是它首先尝试去加载某各类,如果找不到在代理给父类加载器,这与一般的加载器顺序相反


posted @ 2018-03-22 09:41  Morgen会蝎子摆尾  阅读(126)  评论(0编辑  收藏  举报