线程上下文类加载器总结

ContextClassLoader java

为线程上下文加载器,正常的双亲委派模型中,下层的类加载器能够使用上层父加载器加载的对象,可是上层父类的加载器不能够使用子类加载的对象。而有些时候程序的确须要上层调用下层,这时候就须要线程上下文加载器来处理。 编程

这一般发生在JVM核心代码必须动态加载由应用程序动态提供的资源时。拿JNDI为例,它的核心是由JRE核心类(rt.jar)实现的。但这些核心JNDI类必须能加载由第三方厂商提供的JNDI实现。这种状况下调用父类加载器(原初类加载器)来加载只有其子类加载器可见的类,这种代理机制就会失效。解决办法就是让核心JNDI类使用线程上下文类加载器,从而有效的打通类加载器层次结构,逆着代理机制的方向使用类加载器。 服务器

顺便提一下,XML解析API(JAXP)也是使用此种机制。当JAXP仍是J2SE扩展时,XML解析器使用当前类加载器方法来加载解析器实现。但当JAXP成为J2SE核心代码后,类加载机制就换成了使用线程上下文加载器,这和JNDI的缘由类似。 框架

更严重的问题, 某些应用服务器把环境上下文及当前类加载器设置到不一样的类加载器实例上, 而这些类加载器有相同的类路径但却没有委派机制中的父子关系. 想一想这为何十分可怕. 要知道类加载器定义并加载的类实例会带有一个JVM内部的ID号. 若是当前类加载器加载一个类X的实例, 这个实例调用JNDI查找类Y的实例, 这时的上下文的类加载器也能够定义了加载类Y实例. 这个类Y的定义就与当前类加载器看到的类Y的定义不一样. 若是进行强制类型转换, 则产生异常。 spa

这种混乱的情况还将在Java中存在很长时间。在J2SE中还包括如下的功能使用不一样的类加载器: 线程

l        JNDI使用线程上下文类加载器 代理

l        Class.getResource()Class.forName()使用当前类加载器 对象

l        JAXP使用上下文类加载器 blog

l        java.util.ResourceBundle使用调用者的当前类加载器 资源

l        URL协议处理器使用java.protocol.handler.pkgs系统属性并只使用系统类加载器。

l        Java序列化API缺省使用调用者当前的类加载器

其中  ResourceBundle.getBundle()的相关加载能够参考(http://jluwang.iteye.com/blog/1132356)。
 
  通常来讲,上下文类加载器要比当前类加载器更适合于框架编程,而当前类加载器则更适合于业务逻辑编程。
相关文章
相关标签/搜索