线程上下文类加载器是从1.2版本开始出现的,它出现的初衷就是为了“打破双亲委托机制”
Java应用启动时默认的线程上下文类加载器是系统类加载器,在线程中运行的代码可以通过该类加载器来加载类
应用范围;SPI服务广泛使用(Service Provider Interface)
- 传统双亲委托模型下,SPI无法实现,而使用线程上下文来加载器,就可以了实现父ClassLoader使用当前线程Thread.currentThread.getContextClassLoader所指定的类加载器来加载类,即改变了双亲委托模型中的子类请求父类加载器加载类
- 在双亲委托模型下,类加载器是由上至下的,即下层的类加载器会委托上层的类加载器进行加载,但是对于SPI来说,有些接口是由Java核心类库提供的,而核心类库是由启动类加载器加载的,但是这些接口的实现却是由第三方厂商来实现提供的jar,启动类加载器不会加载其他来源的jar包,传统的双亲委托模型就无法满足了
- 线程上下文类加载器使用模式 (获取 --- 使用 --- 还原)如下伪代码
ClassLoader classloader = Thread.currentThread.getContextClassLoader(); -------获取
try {
Thread.currentThread.setContextClassLoader(targetTccl);------使用你需要的类加载器来进行加载类
myMethod();
} catch (){
}finally{
Thread.currentThread.setContextClassLoader(classloader);
}
myMethod里面则调用了Thread.currentThread.getContextClassLoader() 获取当前线程上下文类加载器来做某些事情
当高层提供的统一接让低层去实现,同时又要在高层加载(或实例化)低层类时,就必须要通过线程上下文类加载器来帮助高层的类加载器找到并加载该类 (JDBC,jndi等等)