[英]What is the need of different class loaders in java
我已经读过Java中有不同的类加载器,一种是原始类加载器,也有自定义类加载器,所以我想了解为什么原始类加载器不能为Java中的所有类提供服务? 为什么需要其他类装载机?
主要需要是隔离。
假设页面上有3个applet,每个applet使用库foo.jar的不同版本。 您希望每个小程序都使用其自己的库版本运行,并确保它不会在另一个小程序的脚趾上行走。 这要归功于不同的类加载器。
部署在单个容器上的Web应用程序也是如此。 启动Java容器时未部署任何应用程序,然后部署了应用程序。 您希望容器能够从甚至不知道何时启动的位置加载类。 而且,如果部署了另一个Web应用程序,则您希望该其他应用程序具有自己的类和库,这些类和库与第一个应用程序的类和库是不同的并且是隔离的。
另一个需求是能够从各个位置加载类:文件系统,但也可以加载URL,数据库等。
在许多实际情况下,您需要功能超出系统类装入器提供的功能:
最后一点特别强大(这也是我使用它们的主要原因)。 由于Java字节码在各个平台之间是通用的,因此您可以使用它来检测任何系统上的类:测量调用了哪些方法,抑制对安全性要求很高的调用,将System.out访问转移到您自己的自定义日志记录例程,或者执行高级的动态错误测试。例行程序。
原因之一是安全性。 例如,默认(程序包专用)可见性级别仅允许访问相同程序包中的类, 并由相同的类加载器加载 。 这使得恶意代码更难以访问您的内部API。
参考文献:
假设您正在开发应用程序服务器。 根据要求,您希望在服务器启动时加载类。 原始加载器不知道您的要求,因此您需要编写自己的类加载器。
这个答案很好地总结了为什么即使您可以也不希望对所有类都使用相同的类加载器:
ClassLoader在大型系统和服务器应用程序中用于执行以下操作:
- 模块化系统并在运行时加载,卸载和更新模块
- 并行使用不同版本的API库(例如XML解析器)
- 隔离在同一JVM中运行的不同应用程序(确保它们不会相互干扰,例如通过静态变量)
类装载器的类型:
Boot Strap类加载器 :负责加载核心JAVA API类,即rt.jar中存在的类
rt.jar的位置-> jdk / jre / lib / rt.jar,也称为引导程序类路径。
Bootstrap类加载器从Bootstrap类路径加载类。 Bootstrap是用C或C ++等本机语言实现的,而不是用JAVA实现的。
扩展类加载器:从扩展类路径(即jdk / jre / lib / ext / *。jar)加载类
扩展类加载器是BootStrapClassLoader的子级,它是用JAVA实现的。
对应的JAVA类是sun.misc.Launcher$ExtClassLoader.class
应用程序类加载器:扩展类加载器的子类。 应用程序类加载器从应用程序类路径加载类。 它在内部使用环境类路径。
它在JAVA中实现。 对应的JAVA类是sun.miscLauncher$AppClassLoader.class
类加载器遵循委托层次结构原则 。 每当JVM遇到特定类时,它都会首先检查.class文件的加载位置。 如果已在方法区域中加载了该类,则JVM将考虑该已加载的类,如果不是,则JVM将请求Class Loader Subsystem来加载特定的类。 Class Loader子系统将请求移交给应用程序类加载器,将请求委托给Extension Class加载器,然后委托给BootStrap Class loader,后者搜索引导类路径(如果找不到),Extension Class loader搜索扩展类路径,如果找不到,则查找Application类laoder搜索应用程序类路径,如果仍然找不到该类,则将发生ClassNotFoundException或NoClassDefFoundError。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.