Java类加载器()是Java运行时环境(Java Runtime Environment)的一个部件,负责动态加载Java类到Java虚拟机的内存空间中。类通常是按需加载,即第一次使用该类时才加载。由于有了类加载器,Java运行时系统不需要知道文件与文件系统。对学习类加载器而言,掌握Java的委派概念是很重要的。
每个Java类必须由某个类加载器装入到内存。Java程序可以通过类加载器来利用外部库(即由其他作者编写的软件库)。
JVM中有3个默认的类加载器:
引导(Bootstrap)类加载器。由原生代码(如C语言)编写,不继承自java.lang.ClassLoader。负责加载核心Java库,存储在/jre/lib目录中。
扩展(Extensions)类加载器。用来在/jre/lib/ext,或java.ext.dirs中指明的目录中加载 Java的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。该类由sun.misc.Launcher$ExtClassLoader实现。
Apps类加载器(也称系统类加载器)。根据 Java应用程序的类路径(java.class.path或CLASSPATH环境变量)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。该类由sun.misc.Launcher$AppClassLoader实现。
每个类装载器通过组合的方式包含一个父装载器(parent class loader)。
JDK 1.2之后引入“双亲委派”方式来实现类加载器的层次调用,以尽可能保证JDK的系统API不会被用户定义的类加载器所破坏,但一些使用场景会打破这个惯例来实现必要的功能。
自定义类加载器
开发可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求而不需要完全了解Java虚拟机的类加载的细节。
可用于:
- 运行时装载或卸载类。这常用于:
** 实现脚本语言
** 用于bean生成器
** 允许用户定义的
** 允许命名空间之间的通信。这是CORBA / RMI协议的基础。
- 改变Java字节码的装入,例如:可用于Java类字节码的加密装入。
- 修改已装入的字节码(面向切面编程中用于织入切面代码)。
JEE的类装载
Java EE (JEE)应用程序服务器典型地用树状的一组类装载器从已部署的WAR或EAR文档中装入类。这使得应用程序之间彼此隔离,但共享已部署模块。servlet container一般被实现为多个类装载器。
JAR地狱
和DLL地狱一样,一个组件的特定JAR也存在版本差异,不同版本间的JAR文件的Class文件存在差异(包括Class文件的编译版本、Class的成员结构、Class继承关系等)的话,也会在运行时触发各种因为类文件结果冲突而导致的错误警告。对于Servlet容器,还存在容器所需的JAR与应用内所需的JAR双线冲突的问题。
不同于DLL地狱,Java开发者会使用一些项目管理程序(例如Apache Maven)来解决JAR版本之间的冲突,通过配置依赖关系文件,设定不同组件的JAR版本依赖关系,由项目管理程序自动加载相应合适的JAR,来控制JAR间 的版本关系。而对于Servlet容器,也会通过自己实现类加载器打破JDK的“双亲委派”方式来避免JAR加载冲突。
参考文献
外部链接
- Chuck McManis, "[https://web.archive.org/web/20110713091503/http://www.javaworld.com/jw-10-1996/jw-10-indepth.html The basics of Java class loaders]", 1996
- Brandon E. Taylor, "[http://www.developer.com/java/other/article.php/2248831 Java Class Loading: The Basics] ", 2003
- Jeff Hanson, "[http://www.devx.com/Java/Article/31614 Take Control of Class Loading in Java] ", 2006-06-01
- Andreas Schaefer, "[http://www.onjava.com/pub/a/onjava/2003/11/12/classloader.html Inside Class Loaders] ", 2003-11-12
- Sheng Liang and Gilad Bracha, "[http://citeseer.ist.psu.edu/liang98dynamic.html Dynamic class loading in the Java virtual machine]", In Proceedings of the 13th ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA'98), ACM SIGPLAN Notices, vol. 33, no. 10, ACM Press, 1998, pp. 36–44
- Dr. Christoph G. Jung, "[http://www.roseindia.net/javatutorials/hotdeploy.shtml Classloaders Revisited Hotdeploy] ", Java Specialist Newsletter, 2001-06-07
- Don Schwarz, "[http://www.onjava.com/pub/a/onjava/2005/04/13/dependencies.html?page=1 Managing Component Dependencies Using ClassLoaders] ", 2005-04-13
评论 (0)