Java动态加载插件

Flo*_*oFu 6 java plugins runtime classpath

我想创建一个可以动态加载插件的应用程序,但我没有在互联网上找到任何文献.

困难的是:我事先不知道这个名字.

例如,我有一个插件界面:

public interface Plugin {
    public static Plugin newPlugin();
    public void executePlugin(String args[]);
}
Run Code Online (Sandbox Code Playgroud)

这样在jar文件中实现插件的每个Class 都在列表中实例化:

Method method = classToLoad.getMethod ("newPlugin");
mylist.add(method.invoke(null);
Run Code Online (Sandbox Code Playgroud)
  1. 第一个问题是,我不能在接口中使用静态方法.
  2. 第二个问题是,我不知道如何找到实现接口的所有类

谢谢你的帮助.

Sir*_*hie 24

因此,您似乎希望动态发现Plugin在运行时实现特定接口(例如)的类.你基本上有两个选择:

  1. 使用像osgi这样的组件框架
  2. 使用Java的内部发现过程(ServiceLoader)

由于有许多关于osgi(也是小的)的好教程,我不会在这里详述.要使用Java的内部发现过程,您需要执行以下操作:

  • 将您希望发现的所有"新"类捆绑到一个jar文件中
  • 创建一个新的文件,里面的jar文件:META-INF/services/package.Plugin此处必须使用完整的包预选赛
  • 此文件是一个简单的文本文件,包含Plugin在该jar文件中实现的每个类的完全限定名称
  • 将该jar文件放入(可能已在运行的)应用程序的类路径中
  • 发现服务:

服务发现是这样完成的:

ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class)
for (Plugin p : loader) {
    // do something with the plugin
}
Run Code Online (Sandbox Code Playgroud)

这里有更多细节:http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html

至于接口中的静态方法:不可能.由于静态方法可以在没有类实例的情况下访问,并且接口只是定义方法而没有任何功能,因此它的语义也有些奇怪.因此,静态将允许调用,Interface.doSomething()而接口不定义任何功能,这只会导致混淆.

编辑:

添加了描述元文件中应该包含的内容