在Java中实现动态插件
我想在Java应用程序中实现动态插件function。 理想的情况是:
- 应用程序将使用
getCapabilities()
等方法定义接口Plugin
。 - 插件将是一个JAR
pluginX.jar
其中包含一个实现Plugin
pluginX.jar
类(可能还有其他一些)。 - 用户将
pluginX.jar
放在特殊目录中或设置指向它的配置参数。 用户不一定必须在其类路径中包含pluginX.jar
。 - 该应用程序将找到
PluginXImpl
(可能通过JAR清单,可能通过reflection)并将其添加到注册表。 - 客户端可以获得
PluginXImpl
的实例,例如,通过调用getPluginWithCapabilities("X")
。 用户不一定必须知道插件的名称。
我有一种感觉,我应该能够用peaberry做到这一点,但我无法理解文档。 我花了一些时间学习Guice,所以我的首选答案不是“使用Spring Dynamic Modules” 。
任何人都可以给我一个简单的想法,如何使用Guice / peaberry,OSGi,或只是简单的Java?
使用普通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()以获取所有已配置的插件实现的实例。
你仍然需要提供自己的包装来过滤插件function,但我认为这应该不会太麻烦。
如果你想在24/7环境中的错误修正的运行时ig期间替换插件,OSGI会没问题。 我和OSGI玩了一段时间,但花了太多时间,因为这不是一个要求,如果你删除一个捆绑,你需要一个计划b。
我的简单解决方案是,提供一个包含插件描述符类的类名的属性文件,让服务器调用它们进行注册(包括查询它们的function)。
这显然不是最理想的,但我迫不及待地想要阅读已接受的答案。
您是否有机会利用服务提供商界面 ?
使用Guice实现插件的最佳方法是使用Multibindings 。 链接页面详细介绍了如何使用多重绑定来托管插件。
如果您知道这一点,请道歉,但请查看Class的forName
方法。 它至少在JDBC中用于按类名动态加载特定于DBMS的驱动程序类运行时。
然后我想枚举一个目录中的所有类/ jar文件,加载每个文件并定义一个静态方法getCapabilities()
(或你选择的任何名称getCapabilities()
的接口并不难,它会返回它们的function/描述。对您的系统有意义的术语和格式。