为什么setContextClassLoader()方法放在Thread上?

问题描述 投票:7回答:4

为什么setContextClassLoader()方法放在Thread

什么不同的线程有不同的类加载器?

问题是如果我扩展了一个ClassLoader,加载了一些新的类。到我的自定义类加载器。

现在,我希望它是上下文类加载器,所以我调用方法Thread.currentThread().setContextClassLoader(loader)

这些新类是否仅在当前线程的上下文中可用?或者它是如何工作的?

谢谢

java classloader
4个回答
8
投票

Context类加载器是线程将用于查找类的类加载器。在编写应用程序服务器或类似的东西时,您主要关心这一点。我们的想法是,您可以从应用程序服务器的类加载器中加载的类启动一个线程,然后传递一个子类加载器来处理加载已部署应用程序的类。


2
投票

线程上下文类加载器有点像黑客。

使用反射加载类时,可以使用显式类加载器或直接调用类。使用普通Java代码链接到类时,请求链接的类用作加载器的源。

Thread.setContextClassLoader用于为Thread.getContextClassLoader设置类加载器。随机API(特别是通过ServiceLoader)使用它来通过反射获取类,以便您可以更改实现。根据你的代码改变实现,取决于它在关键时刻运行的线程是一个坏主意。


2
投票

Thread.setContextClassLoaderis用于设置contextClassLoader,如果没有手动设置,它将设置为systemClassLoader,这是Launcher.AppClassLoader,这可以通过检查Launcher的源代码来证明。 enter image description here

那么contextClassLoader的用途是什么?

contextClassLoader提供了围绕类加载委派方案的后门。

然后这个问题成为我们为什么需要这个后门?

来自JavaWorld的文章Find a way out of the ClassLoader maze

以JNDI为例:它的内容由rt.jar中的引导类实现(从J2SE 1.3开始),但这些核心JNDI类可以加载由独立供应商实现并可能部署在应用程序的-classpath中的JNDI提供程序。此方案要求父类加载器(在本例中为原始类加载器)加载对其子类加载器之一可见的类(例如,系统类)。正常的J2SE委派不起作用,解决方法是使核心JNDI类使用线程上下文加载器,从而在与正确委托相反的方向上有效地“隧穿”通过类加载器层次结构。


0
投票

Java类加载器可以分为以下类别

1)Bootstrap类加载器 从JAVA_HOME / jre / lib / rt.jar加载类

2)扩展类加载器< 从JAVA_HOME / jre / lib / ext加载类

3)系统类加载器 应用程序的类路径

我们可以创建自己的类加载器并指定可以加载类的自己的位置,即引用ContextClassLoader

希望能够了解我们为什么需要使用setContextClassLoader()

© www.soinside.com 2019 - 2024. All rights reserved.