类加载器
-
加载器列表:
名 加载哪的类 说明 Bootstrap ClassLoader java_home/jre/lib 无法直接访问 Extension ClassLoader java_home/jre/lib/ext 上级为Bootstrap,显示为null Application ClassLoader classpath 上级为Extension 自定义类加载器 自定以 上级为Application - 存在一个层级关系:会优先询问上级是否已经加载;
-
启动类加载器,Bootstrap ClassLoader:
-
扩展类加载器,Exception ClassLoader:
-
双亲委派:指调用类加载器的loaderClass方法时,查找类的规则;
-
双亲,更应该翻译为上级更为合适,因为它并没有继承关系,
-
检查该类是否已经被本加载器加载;
-
如果没有被加载,判断是否有上级:
- 有上级,在递归调用上级的loadClass();
- 如果没有上级,则由Bootstrap ClassLoader加载;
-
到自己类加载里面,加载,否则报错;
通过报错跳出递归,进入下级寻找;
-
-
双亲委派类加载器:
- mysql的DriverManager是由启动类加载器,加载,其中指明了加载驱动Driver方法;
- 但是驱动Driver不在启动加载路径下,所以在Driver加载中,明确使用了应用加载器【Application ClassLoader】;
-
-
线程上下文类加载【ContextClassLoader】:
- ContextClassLoader:是当前线程使用的类加载,默认是应用程序类加载器,
- 在每个线程启动的时候,jvm默认把应用程序加载器赋值给当前线程;
-
自定义类加载器:
- 什么时候需要自定义加载器:
- 想要加载非classpath随意路径中的类文件;
- 面向接口编程,希望解耦,常用在框架设计;
- 希望隔离不同版本,不同应用的同类型都可以被加载,不冲突,常见于tomcat容器;
- 实现步骤:
- 继承ClassLoader父类;
- 遵从双亲委派机制,需要重写findClass方法;
- 读取类文件的字节码;
- 调用父类的defineClass方法来加载类;
- 使用该类加载器的loadClass方法;
- 确定类相同:包名+类名+类加载器【对象】,三者相同;
- 因此通过内加载器不是同一个对象,判定不是相同类,从而实现了隔离;
- 通常情况下,启动类加载器,扩展应用加载器和应用类加载器都是单例实例化;
- 什么时候需要自定义加载器: