如何使用具有相同全名的两个不可比较的类?

时间:2011-05-20 13:57:17

标签: java spring classloader

问题:我的应用程序使用两个库,这两个库使用第三个库的不兼容版本。有人知道任何类隔离的方法吗?

我听说过类加载器,但我不明白,他们如何能够提供帮助 - 如果我们将加载一个版本的类,我们无法加载另一个类 - 已经加载了类?

我也在考虑Spring,但不知道它是否提供了这种隔离。

3 个答案:

答案 0 :(得分:2)

ClassLoader基本上是赋予JVM中类意义的元素。它们形成了一个层次结构,因为根位于JVM中并加载了java类。 ApplicationClassLoader是您必须考虑的第一个ClassLoader,因为它加载了应用程序的所有类。

加载类时,将解析对其他类的所有引用,并加载这些类。默认情况下,JVM提供了一个系统,其中类加载器首先询问其父级,以查看它们是否已加载类。如果没有,他们会在类路径中搜索

如果两个类位于2个不同的类加载器中,则可以隔离,而不是在app类加载器中。这并不困难。您只需要在指定其父级及其类路径(字节码所在的位置)时创建类加载器(如URLClassLoader)

然后,你告诉他加载课程。它将询问其父级,如果该类尚未加载,它将搜索其类路径并加载它。如果您创建另一个附加到同一父级的类加载器,则第一个加载的类将永远不会被秒看到,因为它们是兄弟姐妹。第二个可以加载一个具有相同名称的类而没有任何问题

这是一个很好的隔离

App Servers使用其他形式的委派来在应用程序之间进行坦诚的隔离。他们重新定义了一个扩展的类加载器,例如URLClassLoader,并通过首先在类路径中搜索类来反转委托过程,然后向父级询问

答案 1 :(得分:1)

  

如果我们要加载一个版本的类,我们就无法加载另一个类   已加载?

不正确。类加载器被认为是类的标识的一部分。如果它由不同的类加载器加载,则它被认为是不同的类。

答案 2 :(得分:-1)

如果至少有一个库是开源的,并且它们所依赖的库是开源的,则无需乱搞类加载器。只需批量重命名所依赖的库的一个版本中的所有包,确保还更改引用这些包的所有代码。嘿presto - 没有名字冲突。这就是Sun实际为JDK所做的事情,当时他们在幕后包括了Xerces和Xalan。