让 2 个不同的独立 Java 程序相互通信的好方法是什么?
我不确定是否要使用 OSGi(但它似乎是唯一仍然获得更新的;jpf 和 jspf 非常旧)。我对插件框架主题非常陌生。我说得对吗?OSGi 只是架构、插件结构等的描述,而 equinox 和所有其他东西都是我必须使用的真正实现?
我让事情变得更精确:我想编写一个核心工具,它应该能够热加载插件,并与它们和 JavaFX GUI 进行双向通信。
我通常使用一个类来控制 GUI,并使用一个附加类来控制算法等(MVC)。但我认为这种风格对于构建基于插件的工具不再有帮助。
我想从一开始就使用好的设计模式,否则最终会变得一团糟。
最佳答案
此问题最简单的解决方案是使用 ServiceLoader
(doc here )。它包含在 Java 中,并且使用起来相当简单:
- 在运行时加载 Jar 文件
- 检测实现特定接口(interface)的类(例如:
your.package.YourService
)。 - 实例化这些类的对象。
Here是一篇非常好的文章,描述了如何做到这一点(注意:您应该将第二个提案与 URLCLassLoader
结合使用;不要动态扩展类路径)。另外,不要忘记在 Jar 的 META-INF 目录中声明您的服务:
If
com.example.impl.StandardCodecs
is an implementation of theCodecSet
service then its jar file also contains a file namedMETA-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/