为什么需要更多的类加载器?

时间:2013-08-29 19:31:02

标签: java java-ee classloader

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

1.Bootstrap类加载器(本机代码)
2.扩展类加载器(sun.misc.Launcher$ExtClassLoader
3.系统类加载器(sun.misc.Launcher$AppClassLoader class
4.自定义类加载器(即应用程序服务器,耳朵类加载器,战争类加载器)

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

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

我猜使用的类加载器依赖于特定的应用服务器。以下是Tomcat class loaders的文档。

在Tomcat中,他们基本上创建了不同的类加载器,可以从不同的位置加载类。例如,公共类加载器从$CATALINA_HOME/lib加载共享库。每个Web应用程序类加载器都将从相应的WEB-INF目录加载类。

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

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