java中不同类加载器的需求是什么

时间:2013-11-28 07:10:18

标签: java class classloader

我已经读过java中有不同的类加载器,一个是原始类加载器,也有自定义类加载器,所以我想理解为什么原始类加载器不能为java中的所有类提供服务? 为什么需要其他类加载器?

6 个答案:

答案 0 :(得分:12)

主要需要隔离。

假设页面上有3个applet,每个applet使用不同版本的库foo.jar。您希望每个applet都使用自己的库版本运行,并确保它不会在另一个applet的脚趾上行走。这要归功于不同的类加载器。

部署在单个容器上的Web应用程序也是如此。在没有部署任何应用程序的情况下启动Java容器,然后部署应用程序。您希望容器能够从它甚至不知道何时启动的位置加载类。如果部署了另一个webapp,您希望这个其他应用程序拥有自己的类和库,这些类和库与第一个应用程序的类和库是不同的。

另一个需求是能够从不同的位置加载类:文件系统,还有URL,数据库或其他任何东西。

答案 1 :(得分:5)

在许多实际情况中,您需要超出系统类加载器提供的功能:

  1. 您可以访问自定义类源(例如,通过http)
  2. 您可以缓存数据块(例如,'如果需要此类,那么让我预先加载其他类')
  3. 您可以合并阻止加载某些类的安全协议
  4. 您可以保留使用哪些类的统计信息,以便稍后优化您的jar存档
  5. 您可以在加载类时执行字节码转换('加载时编织'),例如,修改适合某种模式的类。面向方面的编程实现可以使用这种技术。
  6. 最后一点特别有用(并且是我使用它们的主要原因)。由于Java字节码在各个平台上都是通用的,因此您可以使用它来检测任何系统上的类:测量调用哪些方法,抑制安全关键调用,将System.out访问转移到您自己的自定义日志记录例程,或执行高级动态错误测试例程。

答案 2 :(得分:3)

一个原因是安全。例如,默认(包私有)可见性级别仅允许访问来自同一包的类,并由同一个类加载器加载。这使得恶意代码更难以访问您的内部API。

参考文献:

答案 3 :(得分:0)

假设您正在开发应用程序服务器。根据要求,您将在服务器启动时加载类。原始装载机不了解您的要求&因此你需要编写自己的类加载器。

why write custom class loader

答案 4 :(得分:0)

这个answer很好地总结了为什么你可能不想为所有类使用相同的类加载器,即使你可以:

  

ClassLoader在大型系统和服务器应用程序中用于执行以下操作:

     
      
  • 模块化系统并在运行时加载,卸载和更新模块
  •   
  • 并行使用不同版本的API库(例如XML解析器)
  •   
  • 隔离在同一JVM中运行的不同应用程序(确保它们不会相互干扰,例如通过静态变量)
  •   

答案 5 :(得分:0)

类加载器的类型:

  1. Boot Strap Class loader / Premodial Class Loader
  2. Extension Class Loader
  3. 应用类加载器/系统类加载器
  4. 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

    Application Class Loader: Extension类加载器的子类。应用程序类加载器从Application Class路径加载类。它在内部使用环境类路径。

    它在JAVA中实现。相应的JAVA类是sun.miscLauncher$AppClassLoader.class

    类加载器遵循委托层次结构原则。每当JVM遇到一个特定的类时,首先它将检查已经加载了.class文件的位置。如果已经加载了方法区域,那么JVM将考虑加载的类,如果不是JVM请求类加载器子系统来加载特定的类。类加载器子系统将请求移交给应用程序类加载器,它将请求委托给扩展类加载器然后它委托给BootStrap类加载器搜索引导类路径,如果没有找到,则扩展类加载器搜索扩展类路径,如果没有找到则应用程序类laoder搜索Application Class路径,如果仍未找到该类,则会发生ClassNotFoundException或NoClassDefFoundError。