18

我想在 Java 应用程序中实现动态插件功能。理想情况下:

  • 该应用程序将定义一个Plugin具有类似方法的接口getCapabilities()
  • 插件将是一个 JAR pluginX.jar,其中包含一个类PluginXImpl实现Plugin(可能还有其他一些)。
  • 用户将放入pluginX.jar一个特殊的目录或设置一个指向它的配置参数。用户不一定必须包含pluginX.jar在他们的类路径中。
  • 应用程序会找到PluginXImpl(可能通过 JAR 清单,也可能通过反射)并将其添加到注册表中。
  • 客户端可以获取 的实例PluginXImpl,例如,通过调用类似 的方法getPluginWithCapabilities("X")。用户不一定必须知道插件的名称。

我有一种感觉,我应该能够用peaberry做到这一点,但我无法理解文档。我花了一些时间学习 Guice,所以我的首选答案不是“使用Spring Dynamic Modules ”。

谁能给我一个简单的想法,告诉我如何使用 Guice/peaberry、OSGi 或纯 Java 来做这件事?

4

5 回答 5

17

这实际上很容易使用纯 Java 方法:

由于您不希望用户在启动应用程序之前配置类路径,因此我将首先创建一个 URLClassLoader,其中包含指向插件目录中文件的 URL 数组。使用 File.listFiles 查找所有插件 jar,然后使用 File.toURI().toURL() 获取每个文件的 URL。您应该将系统类加载器 (ClassLoader.getSystemClassLoader()) 作为父级传递给您的 URLClassLoader。

如果插件 jar 包含 META-INF/services 中的配置文件,如 java.util.ServiceLoader 的 API 文档中所述,您现在可以使用 ServiceLoader.load(Plugin.class, myUrlClassLoader) 为您的插件接口获取服务加载器并在其上调用 iterator() 以获取所有已配置插件实现的实例。

您仍然必须为此提供自己的包装器来过滤插件功能,但这应该不会太麻烦,我想。

于 2010-01-20T21:22:57.517 回答
1

如果您想在运行时 ig 替换插件以在 24/7 环境中修复错误,OSGI 会很好。我用 OSGI 玩了一段时间,但花了太多时间,因为它不是必需的,如果你删除一个包,你需要一个计划 b。

然后我的简单解决方案是,提供一个带有插件描述符类的类名的属性文件,并让服务器调用它们进行注册(包括查询它们的功能)。

这显然不是最理想的,但我迫不及待地想阅读接受的答案。

于 2010-01-20T21:43:11.133 回答
1

您有机会利用服务提供者接口吗?

于 2010-01-21T01:19:36.250 回答
1

使用 Guice 实现插件的最佳方式是使用Multibindings。链接页面详细介绍了如何使用多重绑定来托管插件。

于 2010-01-21T08:45:01.540 回答
0

如果您知道这一点,请道歉,但请查看ClassforName的方法。它至少在 JDBC 中用于按类名动态加载特定于 DBMS 的驱动程序类运行时。

然后我想枚举目录中的所有类/jar文件,加载每个文件,并为静态方法 getCapabilities()(或您选择的任何名称)定义一个接口,以任何术语和格式返回它们的功能/描述并不难这对您的系统有意义。

于 2010-01-20T20:55:24.300 回答