5

我知道java中类加载器的层次结构是:

1.Bootstrap 类加载器(在本机代码中)
2. 扩展类加载器(sun.misc.Launcher$ExtClassLoader
3. 系统类加载器(sun.misc.Launcher$AppClassLoader class
4. 自定义类加载器(即应用服务器、ear 类加载器、war 类加载器)

我不清楚为什么需要额外的子类加载器。我可以理解在本机代码中的类加载器之后对“纯 java”类加载器的需求。
我对可能的原因有一些想法,但有人可以为我提供关于这种行为/需要类加载器层次结构的明确解释吗?
一般来说,但也适用于 j2ee。

4

2 回答 2

4

类加载器对于提供各种行为和保护在同一 VM 中运行的不同 Java 程序彼此之间非常有用。我想到了三个主要类别:

  • 类加载器可以以不同的方式实现加载类的过程。例如,您可能有一个类加载器,它从某个服务器检索一个类的字节码,然后将其安装到 JVM 中,或者您可能有一个实际动态生成字节码而不是从文件中读取它的类加载器。
  • 类加载器可以在单个 JVM 中形成分区,以便不同的代码“树”可以拥有具有相同名称的类的不同副本。一个常见的例子是像 Tomcat 这样的 servlet 容器,其中war可能安装了几个 s,它们都有不同版本的库(例如,Apache Commons-Lang)。OSGi 也使用这种方法来确保每个包只能访问它特别请求的类并且不能“泄漏”API。
  • 类加载器可用于实现有关何时对实际类本身进行垃圾收集的不同策略。仅使用默认的类加载器会无限期地保留类,从而导致可怕的 PermGen 错误;使用大量临时类(可能是动态生成的)的应用程序可能希望通过使用一次性类加载器确保它们在不再需要时被释放。
于 2013-08-29T19:46:29.097 回答
0

我猜想使用的类加载器取决于特定的应用服务器。这是Tomcat 类加载器的文档。

在 Tomcat 中,他们基本上创建了不同的类加载器,从不同的位置加载类。例如,通用类加载器从$CATALINA_HOME/lib. 每个 Web 应用程序类加载器都会从各自的WEB-INF目录加载类。

因此,对类加载器的需求主要来自于从不同位置加载的需求,具有一些优先规则(例如,来自的类WEB-INF优先于CATALINA_HOME/lib)。此外,它们允许在不同的类加载器中加载一个类的不同版本。例如,两个 Web 应用程序可以使用Log4j这种方式的两个不同版本。

其他应用服务器可能具有不同的类加载器层次结构,但同样的原因也适用于它们。

于 2013-09-03T07:13:13.233 回答