25

谁能给我一个好的资源或解释一下类加载器背后的概念?我在类加载器http://www.onjava.com/lpt/a/5586上找到了以下资源,但仍然没有帮助。以下问题可能看起来很愚蠢,但试图回答它们总是让我感到困惑。

  • 为什么开发人员要编写自定义类加载器,为什么不调用 Bootstrap 类加载器来调用您的自定义类?定义自定义类加载器需要什么?

  • 为什么有这么多种类加载器?例如:Bootsrap、Comman、Catalina 类加载器等,

    提前致谢。

4

8 回答 8

46

我发现以下创建自定义类加载器的正当理由:

  1. 您希望从非常规来源加载一个类(例如,一个类的字节码存储在数据库中,通过网络存储或由 pidgeons - MessengerPidgeonClassLoader 作为 0 和 1 携带)。对于这种情况,API 中已经有一些 ClassLoader 实现,例如URLClassLoader

  2. 您需要定义不同的层次结构来加载类。ClassLoader 的默认实现首先将搜索委托给父级,然后他们尝试自己加载类。也许您想要不同的层次结构。这就是为什么 OSGI 和 Eclipse 有自己的 ClassLoaders 的原因,因为 Manifest .MF 文件定义了所有类型的奇怪的层次结构路径(例如伙伴类加载)。所有 Eclipse 类加载器都实现了 BundleClassLoader 接口,并且有一些额外的代码可以在 Eclipse 插件中查找资源。

  3. 您需要对字节码进行一些修改。也许字节码是加密的,你会即时解密它(不是说它有帮助,真的,但已经尝试过了)。也许您想“修补”动态加载的类(A la JDO 字节码增强)。

如果您需要从内存中卸载类或加载类而不是在运行时更改其定义,则需要使用与系统类加载器不同的类加载器。例如,一个典型的案例是应用程序从 XML 文件动态生成一个类,然后尝试重新加载该类。一旦一个类在系统类加载器中,就没有办法卸载它并有一个新的定义。

于 2009-02-12T08:42:24.933 回答
32

类加载器的一个常见用途是隔离 JAR。如果您有一个使用插件的应用程序(EclipseMaven 2),那么您可能会遇到这种情况:插件 X 需要 jar A 版本为 1.0,而插件 Y 需要相同的 jar 但版本为 2.0。不过,X 不能在 2.0 版中运行。

如果您有类加载器,则可以创建类的分区(想想由薄桥连接的孤立岛屿;这些桥就是类加载器)。这样,类加载器可以控制每个插件可以看到的内容。

当插件 X 实例化具有静态字段的类 Foo 时,这没有问题,并且不会与插件 Y 中的“相同”类混淆,因为每个类加载器实际上都会创建自己的类 Foo 实例。然后,您在内存中有两个类,其中cl1.getName().equals(cl2.getName())truecl1.equals(cl2)不是。这意味着 cl1 的实例与 cl2 的实例不兼容。这可能会导致无法分配给的奇怪ClassCastExceptions说法。org.project.Fooorg.project.Foo

就像偏远岛屿一样,这两个班级不知道另一个班级的存在。想想在不同岛屿上出生然后长大的克隆人。从 VM 的角度来看,没有问题,因为 Class 类型的实例的处理方式与任何其他对象一样:可以有多个。您认为其中一些是“相同的”对 VM 来说并不重要。

此模式的另一个用途是您可以摆脱以这种方式加载的类:只要确保没有人拥有指向从类加载器加载的类创建的任何对象的指针,然后也忘记类加载器。在GC的下一次运行中,此类加载器加载的所有类都将从内存中删除。这允许您“重新加载”您的应用程序,而无需重新启动整个 VM。

于 2009-02-12T08:30:56.567 回答
3

java类加载器的另一个好链接——Java类加载器

于 2009-04-17T06:58:22.547 回答
2

我在过去写过一些关于使用授权后类加载器的博客:

于 2009-02-12T18:08:11.733 回答
2

在这种情况下,您不能超越原始来源。如果您真的想要内部涂料,硬核,请阅读Java 虚拟机规范的相关部分

于 2009-02-15T10:53:44.737 回答
1

您需要创建自己的 ClassLoader 是非常罕见的。通常,如果您需要,您应该已经非常了解 ClassLoader 的作用。

换句话说,如果您问为什么需要创建自己的 ClassLoader,那么您不需要创建一个;)

话虽如此,我还看到为处理密码学的应用程序创建了一个 ClassLoader。这样,每次您创建 java.netSocket 或某种文件/流对象时,它不会使用 JVM 版本,而是使用它们自己特殊的自定义构建类。通过这种方式,他们可以保证所有信息都已加密并且没有开发人员错误。

但这不是很常见。您无需创建自己的自定义 ClassLoader 即可完成整个 Java 职业生涯。实际上,如果您需要创建一个,您应该真正询问是否有必要。

于 2009-02-12T05:50:10.743 回答
1

一个例子:

Tomcat 使用定制的 WebAppClassloader 从不同的 Web 应用程序中加载和隔离类/jar。

于 2016-10-20T02:27:41.753 回答
0

为什么开发人员要编写自定义类加载器,为什么不调用 Bootstrap 类加载器来调用您的自定义类?定义自定义类加载器需要什么?

根据应用程序,开发人员可能会覆盖或完全替换类加载机制以满足他们的需求。

例如,我使用了一个应用程序,其类是从 LDAP 加载的:S

其他应用需要独立的类管理(比如大多数支持热部署的应用服务器)

关于资源,网络上有大量的资源,根本无法列出。

于 2009-02-12T05:29:35.130 回答