Java类加载器

时间:2009-02-12 05:22:28

标签: java classloader dynamic-class-loaders

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

  • 为什么开发人员编写自定义类加载器,为什么不调用Bootstrap类加载器来调用自定义类?有什么需要定义自定义类加载器?
  • 为什么有这么多种类的装载机?例如:Bootsrap,Comman,Catalina类装载机等,

    提前致谢。

8 个答案:

答案 0 :(得分:45)

我发现了以下有效创建自定义类加载器的原因:

  1. 您希望从非常规源加载类(例如,一个类的字节码存储在数据库中,通过网络或carried as 0 and 1s by pidgeons - MessengerPidgeonClassLoader)。对于此类情况,API中已存在一些ClassLoader实现,例如URLClassLoader

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

  3. 您需要对字节码进行一些修改。也许字节码是加密的,你可以动态解密它(Not that it helps, really, but has been tried)。也许你想“修补”动态加载的类(一个JDO字节码增强)。

  4. 如果需要从内存中卸载类,或者加载类而不是在运行时更改其定义,则需要使用与System Classloader不同的类加载器。典型的情况是,例如,从XML文件动态生成类的应用程序,然后尝试重新加载此类。一旦类在System Classloader中,就无法卸载它并有一个新的定义。

答案 1 :(得分:33)

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

如果你有类加载器,你可以创建类的分区(想想通过瘦桥连接的孤岛;桥是类加载器)。这样,类加载器就可以控制每个插件可以看到的内容。

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

在这种情况下,你无法超越原始来源。如果确实想要内部涂料,硬核,请阅读the relevant bits of the Java Virtual Machine Specification

答案 4 :(得分:2)

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

答案 5 :(得分:1)

您需要创建自己的ClassLoader极为罕见。而且如果你需要的话,你应该已经对ClassLoader的作用有了很好的理解。

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

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

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

答案 6 :(得分:0)

  

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

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

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

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

关于资源,网络中有TONS,根本无法列出。

答案 7 :(得分:0)

一个例子:

Tomcat使用自定义的WebAppClassloader来加载和隔离来自不同Web应用程序的类/ jar。