我正在编写一个库,允许人们使用插件框架(如果您熟悉的话,它是 JPF)来提供某些接口的实现。插件不存储在类路径中。该框架为每个插件提供了一个 ClassLoader,因此当请求接口“MyInterface”的名为“MyImpl”的实现时,我可以找到正确的插件,然后使用该插件的 ClassLoader 加载类,我可以从中创建一个实例如果我对构造函数有所了解。到现在为止还挺好。
但是,现在我有一个案例,我需要调用一个仅在该特定实现上可用的方法。所以,有两种方法我可以尝试做到这一点:
方法一:
// 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();
方法二:
// 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 + 安装插件时,将类文件复制到类路径中的另一个目录,以便系统类加载器可以加载它们(导致其他问题)
所以,我的问题是:
- 我是否错过了另一个更好的想法?
- 如果我做 B,我会在运行时遇到问题吗?毕竟,使用 MyImpl 的类可能已经使用系统类加载器加载了。所以,一旦它看到
MyImpl foo
,它会不会尝试使用系统类加载器加载 MyImpl,这会失败(即使 Plugins.newInstance 调用会提供 MyImpl 的实例)?