java - 插件框架和双向程序通信

标签 java plugins osgi

让 2 个不同的独立 Java 程序相互通信的好方法是什么?

我不确定是否要使用 OSGi(但它似乎是唯一仍然获得更新的;jpf 和 jspf 非常旧)。我对插件框架主题非常陌生。我说得对吗?OSGi 只是架构、插件结构等的描述,而 equinox 和所有其他东西都是我必须使用的真正实现?

我让事情变得更精确:我想编写一个核心工具,它应该能够热加载插件,并与它们和 JavaFX GUI 进行双向通信。

我通常使用一个类来控制 GUI,并使用一个附加类来控制算法等(MVC)。但我认为这种风格对于构建基于插件的工具不再有帮助。

我想从一开始就使用好的设计模式,否则最终会变得一团糟。

最佳答案

此问题最简单的解决方案是使用 ServiceLoader (doc here )。它包含在 Java 中,并且使用起来相当简单:

  1. 在运行时加载 Jar 文件
  2. 检测实现特定接口(interface)的类(例如:your.package.YourService)。
  3. 实例化这些类的对象。

Here是一篇非常好的文章,描述了如何做到这一点(注意:您应该将第二个提案与 URLCLassLoader 结合使用;不要动态扩展类路径)。另外,不要忘记在 Jar 的 META-INF 目录中声明您的服务:

If com.example.impl.StandardCodecs is an implementation of the CodecSet service then its jar file also contains a file named

META-INF/services/com.example.CodecSet 

This file contains the single line:

com.example.impl.StandardCodecs    # Standard codecs

通过选择这种方法,您的核心程序自然会拥有插件的句柄,因此能够轻松地与它们进行通信。为了确保双向通信(即插件调用您的核心程序),我建议创建一个您的核心程序将实现的接口(interface),并将该接口(interface)传递给您的插件。

插件界面:

public interface Plugin { 
   public void doPluginStuff(Caller caller);
}

核心程序Caller接口(interface):

public interface Caller {
   public void sendBackResults(Object results);
}

插件实现(在单独的 Jar 文件中):

public class AParticularPlugin implements Plugin {
   public void doPluginStuff(Caller caller){
      caller.sendBackResults("Hello world");
   }
}

核心程序:

public class CoreProgram implements Caller {

   public void callPlugin(URL[] urlToJarFiles){
      URLClassLoader ucl = new URLClassLoader(urlToJarFiles);
      ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, ucl);
      Iterator<Plugin> plugins = sl.iterator();
      while (plugins.hasNext())
         plugins.next().doPluginStuff(this);
   }

   public void sendBackResults(Object results){
      System.out.println(results.toString());
   }

}

关于java - 插件框架和双向程序通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31043880/

相关文章:

java - Android 7.1.1 无法在外部存储中创建文件或文件夹。 FileNotFoundException

osgi - OSGi 中的类路径扫描

java - 嵌入式 jetty 与 Resteasy 的集成

javascript - 单击 anchor 标记后,jQuery Mobile 不会移动到下一页

java - 有没有办法在另一个注释中使用注释的值?

plugins - 如何在自定义 gradle 插件中迭代 gradle 依赖项?

javascript - 回调函数不适用于 HTML5 视频播放器

javascript - http ://responsive-nav. com/在 Android 上变得不稳定的动画

terminology - 什么是 OSGi?它的使用示例有哪些?

osgi - Equinox和处女座有什么区别?