ClassLoader功能说明
下文笔者将讲述ClassLoader的功能详解,如下所示
类载入
ClassLoader详解
ClassLoader的简介:
对类请求提供服务
当JVM需要某类时
它使用类的全限定名向ClassLoader索取类
ClassLoader将返回,这个类class对象
ClassLoader功能
ClassLoader的功能:
载入系统中所有Resources(Class,文件,来自网络的字节流等)
使用ClassLoader这个类可将资源载入到JVM中
我们都知道每个class都有一个reference
指向自己的ClassLoader
例:
Class.getClassLoader()
注意事项:
1.数组的ClassLoader是其元素的ClassLoader
2.如果是基本数据类型数组,则这个数组没有ClassLoader
Class.getClassLoader()的工作原理
自JDK1.2以后
ClassLoader在进行类加载时,使用双亲委派模式,如下所示:
ClassLoader在载入类库时先让Parent寻找,Parent找不到才自己找
ClassLoader指以下三种:
Bootstrap ClassLoader、Extension ClassLoader和 App ClassLoader
三个Loader简介:
Bootstrap ClassLoader:
native方法,使用C++编写,在Java中看不到它,是null
用于加载核心类库(lib中的类库)
Extension ClassLoader:加载lib/ext中的类库
App ClassLoader:加载Classpath中的类库
三者对应的层级关系
App ClassLoader的Parent是Extension ClassLoader
Extension ClassLoader的Parent为Bootstrap ClassLoader。
Class.getClassLoader()加载类的原理
当JVM需加载一个类时,
首先由BootStrap进行寻找
找不到再由Extension ClassLoader寻找
最后由App ClassLoader查找
Tomcat的ClassLoader结构图:
Bootstrap
|
System
|
Common
/
Catalina Shared
/
Webapp1 Webapp2 ...
线程中ClassLoader简介
每个线程中都有一个contextClassLoader
contextClassLoader的功能:
用于动态的载入其它类
如:
Thread.currentThread().setContextClassLoader(...);
Thread.currentThread().getContextClassLoader()
this.getClass.getClassLoader();
//得到Classloader是静态的,表明类的载入者是谁;
Thread.currentThread().getContextClassLoader();
//得到Classloader是动态,
执行者Classloader
tomcat中ClassLoader
Tomcat中
WebApp的ClassLoader的工作原理与java中有小小不同
它先试图自己载入类(在ContextPath/WEB-INF/...中载入类)
当无法载入时,再请求父ClassLoader完成
Tomcat中
WEB APP线程的contextClassLoader是WebAppClassLoader
Tomcat Server线程的contextClassLoader是CatalinaClassLoader
获得ClassLoader的几种方法
java中我们有以下三种获取ClassLoader的方法
this.getClass.getClassLoader(); // 使用当前类的ClassLoader
Thread.currentThread().getContextClassLoader(); // 使用当前线程的ClassLoader
ClassLoader.getSystemClassLoader(); // 使用系统ClassLoader,即系统的入口点所使用的ClassLoader。
(system ClassLoader与根ClassLoader有些区别
如:JVM下system ClassLoader通常为App ClassLoader)
资源载入
java中所有资源 可使用ClassLoader载入到JVM里例:
类载入
1. 使用Class静态方法Class.forName Class cls = Class.forName("com.java265.test"); T t = (T)cls.newInstance(); 2. 使用ClassLoader ClassLoader cl; // 如何获得ClassLoader参考1.6 Class cls = cl.loadClass("com.java265.test"); // 使用第一步得到的ClassLoader来载入B T t = (T)cls.newInstance(); // 有B的类得到一个B的实例 3. 直接new T t = new T();
文件载入(如配置文件)
如果com.java265.Test类中
需要读取文件夹 /com/Java/config中的文件 application.properties
我们可以使用IO的模式读取
如:
直接IO
File f = new File("D:/test/com/java265/config/application.properties"); // 使用绝对路径
//File f = new File("com/java265/config/application.properties"); // 使用相对路径
InputStream is = new FileInputStream(f);
注意事项:
我们可使用java.util.Properties.load(is)
将内容读到Properties里
但是Properties的默认编码是ISO-8859-1
方法2:
使用ClassLoader读取文件
InputStream is = null;
is = this.getClass().getClassLoader().getResourceAsStream(
"com/java265/config/application.properties");
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(
"com/java265/config/application.properties");
is = ClassLoader.getSystemResourceAsStream("com/java265/config/application.properties");
3.使用ResourceBundle
ResourceBundle bundle = ResourceBundle.getBoundle("com.java265.config.application");
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


