学习ClassLoader有几个关注点:
From: http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
1. java.lang.ClassLoader
中的关键方法
方法
说明
getParent()
|
返回该类加载器的父类加载器。
|
loadClass(String name)
|
加载名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
|
findClass(String name)
|
查找名称为 name 的类,返回的结果是 java.lang.Class 类的实例。
|
findLoadedClass(String name)
|
查找名称为 name 的已经被加载过的类,返回的结果是 java.lang.Class 类的实例。
|
defineClass(String name, byte[] b, int off, int len)
|
把字节数组 b 中的内容转换成 Java 类,返回的结果是 java.lang.Class 类的实例。这个方法被声明为 final 的。
|
resolveClass(Class<?> c)
|
链接指定的 Java 类。
|
2. 类加载器的Delegate
除了引导类加载器之外,所有的类加载器都有一个父类加载器。类加载器在尝试自己去查找某个类的字节代码并定义它时,会先代理给其父类加载器,由父类加载器先去尝试加载这个类,依次类推。通过代理模式,对于 Java 核心库的类的加载工作由引导类加载器来统一完成,保证了 Java 应用所使用的都是同一个版本的 Java 核心库的类,是互相兼容的。比如java.lang.Object
3. 类的定义加载器与初始加载器
真正完成类的加载工作的类加载器和启动这个加载过程的类加载器,有可能不是同一个。真正完成类的加载工作是通过调用 defineClass
来实现的;而启动类的加载过程是通过调用 loadClass
来实现的。前者称为一个类的定义加载器(defining loader),后者称为初始加载器(initiating loader)。在 Java 虚拟机判断两个类是否相同的时候,使用的是类的定义加载器。也就是说,哪个类加载器启动类的加载过程并不重要,重要的是最终定义这个类的加载器。两种类加载器的关联之处在于:一个类的定义加载器是它引用的其它类的初始加载器。如类 com.example.Outer
引用了类 com.example.Inner
,则由类 com.example.Outer
的定义加载器负责启动类 com.example.Inner
的加载过程。
4. 线程上下文类加载器
java.lang.Thread getContextClassLoader() / setContextClassLoader(ClassLoader cl)
如果没有通过 setContextClassLoader(ClassLoader cl)
方法进行设置的话,线程将继承其父线程的上下文类加载器。Java 应用运行的初始线程的上下文类加载器是系统类加载器。在线程中运行的代码可以通过此类加载器来加载类和资源。
这通常发生在JVM核心代码必须动态加载由应用程序动态提供的资源时。拿JNDI为例,它的核心是由JRE核心类(rt.jar)实现的。但这些核心JNDI类必须能加载由第三方厂商提供的JNDI实现。这种情况下调用父类加载器(原初类加载器)来加载只有其子类加载器可见的类,这种代理机制就会失效。解决办法就是让核心JNDI类使用线程上下文类加载器,从而有效的打通类加载器层次结构,逆着代理机制的方向使用类加载器。
常见的 SPI 有 JDBC、JCE、JNDI、JAXP 和 JBI 等。这些 SPI 的接口由 Java 核心库来提供。这些 SPI 的实现代码很可能是作为 Java 应用所依赖的 jar 包被包含进来,可以通过类路径(CLASSPATH)来找到,如实现了 JAXP SPI 的 Apache Xerces 所包含的 jar 包。线程上下文类加载器正好解决了这个问题。如果不做任何的设置,Java 应用的线程的上下文类加载器默认就是系统上下文类加载器。在 SPI 接口的代码中使用线程上下文类加载器,就可以成功的加载到 SPI 实现的类。线程上下文类加载器在很多 SPI 的实现中都会用到
5. 来自网络的类加载器实现需要注意的
类 NetworkClassLoader
负责通过网络下载 Java 类字节代码并定义出 Java 类。在通过 NetworkClassLoader
加载了某个版本的类之后,一般有两种做法来使用它。第一种做法是使用 Java 反射 API。另外一种做法是使用接口。需要注意的是,并不能直接在客户端代码中引用从服务器上下载的类,因为客户端代码的类加载器找不到这些类。使用 Java 反射 API 可以直接调用 Java 类的方法。而使用接口的做法则是把接口的类放在客户端中,从服务器上加载实现此接口的不同版本的类。在客户端通过相同的接口来使用这些实现类。
6. Web/Java EE 应用类加载器 delegate的例外
以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。
分享到:
相关推荐
java 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loader
Java Class Loader总结
自己收集的java class loader相关的一些网络资源文档, 希望对大家有所帮助
深入 Java 的Class Loader(类加载器)
Dynamic class loading in the Java Virtual Machine
应用服务器类加载器 共享库 类加载器问题诊断 资源及参考资料
Class Loader 是一个可视化的基本 .net 2.0 软件。 使用类加载器,您可以在没有命令提示符的情况下执行 .class 文件。 只需打开类文件!
轻量级C ++对象动态发现和加载机制。 使您可以轻松地将插件功能添加到C ++程序。 支持使用XML文件将实现类动态映射到DLL。
NULL 博文链接:https://sbiigu.iteye.com/blog/323180
Inside Class Loader-----Codes Inside Class Loader-----Codes Inside Class Loader-----Codes Inside Class Loader-----Codes Inside Class Loader-----Codes
log.error("Class loader creation threw exception", t); System.exit(1); } } private ClassLoader createClassLoader(String name, ClassLoader parent) throws Exception { //CatalinaProperties解析$...
class-loader测试工程
The Class Loader Architecture The Java Class File The Java API The Java Programming Language Architectural Tradeoffs Future Trends On the CD-ROM The Resources Page 2 Platform independence Why ...
JCL是可配置,动态和可扩展的自定义类加载器,可直接从Jar文件和其他来源加载Java类。 它还可以与Web应用程序和Spring等IoC框架集成,并支持OSGi引导委派。
class_loader_utility.cc
主要介绍了Java中的类加载器,是Java入门学习中的基础知识,需要的朋友可以参考下
Class Loader Registry Update J2EE Adapter Active Object Framework Lookup Plug-in DB Express Node Action View Window Package Node Node Builder Explorer View Prepare Node Action/Action Object Action ...
Method area: holds the details of each class loaded by the class loader subsystem. Heap: holds every object being created by the threads during execution Thread specific runtime data areas: Program ...
js 类加载器(Java) 一种免费软件工具,用于捆绑和提供具有内置依赖项检测功能的大型 Javascript 代码库。 请参阅网站 和 github 仓库: : 了解更多信息。
你可以创建个新的class loader,然后用loadClass加载,再newInstance;原来加载的classloader是不能重新加载的;这算是一个典型的容器思路。 《深入理解java虚拟机》 2、对java“书写一次,到处运行”(Write once, ...