为什么setContextClassLoader()
方法放在Thread
上?
什么不同的线程有不同的类加载器?
问题是,如果我扩展了ClassLoader
,那么会加载一些新类。到我的自定义类加载器。
现在,我希望它成为上下文类加载器,因此我调用方法Thread.currentThread().setContextClassLoader(loader)
。
这些新类是否只能在当前线程的上下文中使用?或者它是如何工作的?
由于
答案 0 :(得分:8)
Context类加载器是线程将用于查找类的类加载器。在编写应用程序服务器或类似的东西时,您主要关心这一点。我们的想法是你可以从应用程序服务器的类加载器中加载的类中启动一个线程,然后传递一个子类加载器来处理加载已部署应用程序的类。
答案 1 :(得分:2)
线程上下文类加载器有点像黑客。
使用反射加载类时,可以使用显式类加载器,也可以使用直接调用类。使用普通Java代码链接到类时,请求链接的类用作加载器的源。
Thread.setContextClassLoader
用于设置Thread.getContextClassLoader
的类加载器。随机API(特别是通过ServiceLoader
)使用它来通过反射获取类,以便您可以更改实现。根据你的代码改变实现,取决于它在关键时刻运行的线程是一个坏主意。
答案 2 :(得分:2)
Thread.setContextClassLoader
用于设置contextClassLoader,如果没有手动设置,它将设置为Launcher.AppClassLoader
的systemClassLoader,这可以通过检查Launcher的源代码来证明。
那么contextClassLoader的用途是什么?
contextClassLoader提供了围绕类加载委派方案的后门。
那么这个问题就变成了为什么我们需要这个后门?
来自JavaWorld的文章Find a way out of the ClassLoader maze
以JNDI为例:它的内容由rt.jar中的引导类实现(从J2SE 1.3开始),但这些核心JNDI类可能加载由独立供应商实现并可能部署在应用程序中的JNDI提供程序。 ; s -classpath。此方案要求父类加载器(在本例中为原始类加载器)加载对其子类加载器之一可见的类(例如,系统类)。 正常的J2SE委派不起作用,解决方法是使核心JNDI类使用线程上下文加载器,从而有效地“隧道化”#34;通过类加载器层次结构与正确委派相反的方向。
答案 3 :(得分:0)
Java类加载器可以分为以下类别
1)Bootstrap类加载器
加载类
从JAVA_HOME / jre / lib / rt.jar2)扩展类加载器<
加载类
从JAVA_HOME / jre / lib / ext
3)系统类加载器
申请的类路径
我们可以创建自己的类加载器并指定可以加载类的自己的位置,即引用ContextClassLoader
希望能够了解我们为什么需要使用setContextClassLoader()