ContextClassLoader 类加载器的学习笔记

ContextClassLoader 类加载器

ContextClassLoader是一种与线程相关的类加载器,每一个Thread都有一个相关联的Context ClassLoader(由native方法建立的除外),可以通过Thread.setContextClassLoader()方法设置。如果你没有主动设置,Thread默认继承Parent Thread的 Context ClassLoader。如果你整个应用中都没有对此作任何处理,那么 所有的Thread都会以应用类加载器作为Context ClassLoader。

java程序在运行时模式的上下文类加载器的应用

比如Java中的SPI(Service Provider Interface)是面向接口编程的,服务规则提供者会在JRE的核心API里面提供服务访问接口,而具体的实现则由其他开发商提供.我们知道Java核心API,比如rt.jar包,是使用Bootstrap ClassLoader加载的,而用户提供的jar包是有AppClassLoader加载。并且我们知道一个类由类加载器A加载,那么这个类依赖的类也应该由相同的类加载器加载.那么Bootstrap ClassLoader加载了 服务提供者在rt.jar里面提供的 实现类的API类(ServiceLoader),那么这些API类里面依赖的类应该也是有Bootstrap ClassLoader来加载.而上面说了用户提供的Jar包有AppClassLoader加载,所以需要一种违反双亲委派模型的方法,线程上下文类加载器

父Classloader可以使用当前线程Thread.currentthread().getContextLoader()中指定的classloader中加载的类。颠覆了父ClassLoader不能使用子Classloader或者是其它没有直接父子关系的Classloader中加载的类这种情况。

import java.sql.Driver;
import java.util.Iterator;
import java.util.ServiceLoader;
public class MyTest1 {
    public static void main(String[] args) {
        ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
        Iterator<Driver> iterator = loader.iterator();
        while(iterator.hasNext()){
            Driver driver = iterator.next();
            System.out.println("driver:" + driver.getClass()+",loader"+driver.getClass().getClassLoader());
        }
        System.out.println("当前线程上下文类加载器" + Thread.currentThread().getContextClassLoader());
        System.out.println("ServiceLoader的类加载器" + ServiceLoader.class.getClassLoader());
    }
}

/*运行结果
driver:class com.mysql.jdbc.Driver,loader:sun.misc.Launcher$AppClassLoader@18b4aac2
driver:class com.mysql.fabric.jdbc.FabricMySQLDriver,loader:sun.misc.Launcher$AppClassLoader@18b4aac2
当前线程上下文类加载器sun.misc.Launcher$AppClassLoader@18b4aac2
ServiceLoader的类加载器null   null代表是Bootstrap ClassLoader
*/

Thread Context ClassLoader多运用与框架中,因为它可以摆脱传统类加载委托机制,使框架能够使用通过不同类加载器加载的类对象。

在实际使用时一般都用下面的经典结构:(获取-使用-还原)


try{

	Thread.currentThread().setContextClassLoader(targetClassLoader);

	mythod()//使用我们需要的使用的类加载器工作

}finally{

	Thread.currentThread().setContextClassLoader(classLoader);//还原

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值