我正在编写一个库,我允许人们使用插件框架提供某些接口的实现(如果您熟悉的话,它是JPF)。插件不存储在类路径中。该框架为每个插件提供了一个ClassLoader,因此当请求接口“MyInterface”的实现命名为“MyImpl”时,我可以找到正确的插件,然后使用该插件的ClassLoader来加载类,我可以从中创建一个实例如果我对构造函数有所了解。到目前为止一切都很好。
但是,现在我需要调用一个仅在该特定实现上可用的方法。所以,有两种方法我可以尝试这样做:
方法1:
// Makes sure that MyImpl has been loaded, using the custom classloader
Plugins.getClass(MyInterface.class, "MyImpl");
// This line will not compile because MyImpl is not available at build time
MyImpl foo = new MyImpl();
// If I could get this far, this line would work:
foo.methodOnlyInMyImpl();
方法2:
// This call will get an instance of MyImpl (already written and tested)
MyInterface foo = Plugins.getInstance(MyInterface.class, "MyImpl");
// Compiler error because there is no MyInterface.methodOnlyInMyImpl method.
foo.methodOnlyInMyImpl()
方法1是两者中的清洁程序,因为它最类似于如果类是“正常”并且无法通过插件访问而编写代码的方式。但是,都没有编译。
我到目前为止提出的选项:
A.使用方法2,但使用反射来执行methodOnlyInMyImpl方法调用(请,不!)
B.将插件类放在构建路径中,然后使用方法1,它将编译。 (我目前最喜欢的)
C. B +安装插件时,将类文件复制到类路径中的另一个目录,这样系统类加载器就可以加载它们(导致其他问题)
所以,我的问题是:
MyImpl foo
,就不会尝试使用系统类加载器加载MyImpl,这会失败(即使Plugins.newInstance调用会提供MyImpl的实例)?答案 0 :(得分:3)
首先,当您需要针对实际实现实施时,您从插件机制获得了什么好处?该插件应该实现一个接口,您可以通过该接口使用该实现。
我与JPF并不相似,但是当由不同的类加载器加载时,java类永远不兼容。但有两种可能的方式:
界面在您的类加载器中,插件类加载器将您的类加载器作为父类,因此其界面与您的相同。当在接口中声明方法时,代码2应该与此一起使用。
您可以使用序列化。这是一种在独立类加载器之间传输数据对象更有用的有限方法。我需要使用它来通过两个webapps之间的请求参数进行跨上下文调度。
答案 1 :(得分:2)
上一个问题中提到了一个名为TransLoader的库。以下是来源的网址:http://code.google.com/p/transloader/。