线程上下文类加载器

本文介绍了Java中的类加载器,特别是当前类加载器和线程上下文类加载器的概念及作用。线程上下文类加载器用于打破双亲委托模型,允许在SPI等场景下加载非父类加载器能触及的类。同时,展示了线程上下文类加载器的使用模式,并解释了其在jdbc等接口实现加载中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当前类加载器(Current Classloader)

每一个类都会使用自己的类加载器(即加载自身的类加载器)来去加载其他类(指的是所依赖的类)如果ClassX引用了ClassY,那么ClassX的类加载器就会去加载ClassY(前提是ClassY尚未被加载)

线程上下文类加载器(Context Classloader)

线程上下文类加载器是由jdk1.2引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader cl)分别用来获取喝设置上下文类加载器。如果没有通过setContextClassLoader(ClassLoader cl)进行设置的话,线程将继承其父线程的上下文类加载器。

Java应用运行时的初始线程的上下文类加载器时系统类加载器。在线程中运行的代码可以通过该类加载器来加载类与资源。

线程上下文类加载器的重要性:

SPI ( Service Provider Interface )

父ClassLoader可以使用当前线程Thread.currentThread().getContextLoader()所指定的classLoader加载的类。这就改变了父ClassLoader不能使用子ClassLoader或者其他没有直接父子关系的ClassLoader加载的类的情况,即改变了双亲委托模型。

线程上下文类加载器就是当前线程的Current ClassLoader

在双亲委托模式下,类加载时由下向上的,即下层的类加载器会委托上层的类加载器进行加载。但对于SPI来说,有些接口是Java核心库提供的,而java核心库是由启动类加载器进行加载,而这些接口的实现却是来自于不同的厂商提供的jar包,java的启动类加载器是不会加载这些jar包,这样传统的双亲委托模式就无法满足SPI的要求,而通过当前线程设置上下文类加载器,就可以由设置的上下文类加载器来实现对于接口实现类的加载

例如:jdbc的连接就是在jdk中声明了接口,但是实现却是由不通厂商进行编写的

线程上下文加载器的一般使用模式(获取 - 使用 - 还原

ClassLoader calssLoader = Thread.currentThread().getContextClassLoader();

try {
    //设置线程上下文类加载器为自定义的加载器
    Thread.currentThread.setContextClassLoader(targetTccl);
    myMethod(); //执行自定义的方法
} finally {
    //还原线程上下文类加载器
    Thread.currentThread().setContextClassLoader(classLoader);
}

myMethod里面调用了Thread.currentThread().getContextClassLoader(),获取当前线程上下文类加载器做某些事情。如果一个类由类加载器A加载,那么这个依赖类也是由相同的类加载的(如果该依赖类之前没有被加载过的话)

ContextClassLoader的作用就是为了破坏加载委托机制。

当高层提供了统一的接口让低层去实现,同时又要在高层加载(实例化)底层的类时,就必须要通过线程上下文类加载器来帮助高层的ClassLoader找到并加载该类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值