首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我自己的装载机?

我自己的装载机?
EN

Stack Overflow用户
提问于 2009-02-05 12:29:05
回答 4查看 1.7K关注 0票数 2

这是我遇到的问题。有一个运行在Java1.3上的大型遗留应用程序,它使用外部API,比如MyAPI v1.0。MyAPI 1.0的确切实现位于应用程序使用的类路径中的某个位置。还有一种机制,允许应用程序使用外部代码(某种插件机制)。现在我有了另一个java库(MyLib.jar),它使用MyAPI v2.0 (它不是100%向后兼容v1.0),我必须使用这个插件机制从原来的应用程序中使用它。所以我不得不让两个(不相容!)相同API的版本一起工作。具体来说,我想在从MyAPI类调用MyLib.jar类时使用MyAPI v2.0,在所有其他情况下使用MyAPI 1.0。

MyAPI 1.0位于类路径中,因此默认情况下将使用它,没关系。我可以创建自己版本的类加载器,从MyAPI 2.0加载类-没问题。但我该怎么把这一切结合起来呢?问题:

  1. MyLib.jar对象实例化了很多(!)MyAPI 2.0中的类实例。这是否意味着我必须通过反射完成所有这些实例化(指定我自己的类加载器)?
  2. 如果一些MyAPI 2.0对象被实例化并在内部实例化来自MyAPI的另一个对象,那么它将使用什么类加载程序?它是使用我的类加载程序还是默认的?
  3. 只是一般的,我的方法听起来合理吗?有更好的方法吗?
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-02-05 12:48:56

让我们从回答第二个问题开始:当从某个类引用到另一个类时,它将由加载原始类的同一个类加载器加载(当然,除非类加载器没有成功地找到类,然后将委托给它的父类加载器)。

话虽如此,为什么您的整个MyLib.jar不通过自定义类加载器加载,然后它可以以常规方式引用新版本的API。否则,您将遇到问题,因为您必须始终使用对象类型和反射。

票数 3
EN

Stack Overflow用户

发布于 2009-02-05 12:41:32

您需要小心使用类加载器。如果您按照您的建议进行操作,那么即使在使用类加载器进行MyAPI 2.0时,您也几乎总是会得到MyAPI 1.0。其原因是如何使用类加载器加载类。类总是先从父类加载器加载。

“ClassLoader类使用委托模型搜索类和资源。ClassLoader的每个实例都有一个相关联的父类加载器。当请求查找类或资源时,ClassLoader实例将把对类或资源的搜索委托给其父类加载器,然后再试图查找类或资源本身。虚拟机的内置类加载器(称为”引导类加载器“)本身没有父类,但可能充当ClassLoader实例的父类。

要正确地提供两个API之间的隔离,您需要两个类加载器(或者除了主要应用程序一个之外,还有两个)。

代码语言:javascript
复制
Parent - System classloader
  |- Classloader1 - Used to load MyAPI 1.0
  |- Classloader2 - Used to load MyAPI 2.0

现在请回答你的问题。您可能要做的是将使用API的大部分逻辑移到类加载器中。除了MyAPI 1.0/2.0之外,您还应该加载应用程序中使用这些部分的部分。然后,父应用程序只需调用一个使用API的方法。通过这种方式,您只需进行一次反射调用就可以启动应用程序,而应用程序中的所有内容都只使用标准引用。

票数 2
EN

Stack Overflow用户

发布于 2009-02-05 12:43:07

您可以在没有反射的情况下使用花哨的ClassLoader来完成这一任务。

基本上,类加载程序必须说“如果加载类来自此jar,则从类路径B加载,否则使用主ClassLoader”。

这比这要复杂一些,但是如果你从这个想法开始,你就会解决的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/515702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档