我想添加一个从外部向我的程序添加更多“命令”的系统。
基本上,与我的 jar(可执行文件)位于同一目录中的文件夹可以具有不同数量的“扩展”
每个“扩展”都是一个 .class 文件,它扩展了某个抽象类,该抽象类具有为识别等定义的方法。
但是,我似乎无法确定是否可以.class
从我的主包外部控制这些文件。
这可能吗?如果有怎么办?如果没有,我可以尝试其他选择吗?
谢谢!
我想添加一个从外部向我的程序添加更多“命令”的系统。
基本上,与我的 jar(可执行文件)位于同一目录中的文件夹可以具有不同数量的“扩展”
每个“扩展”都是一个 .class 文件,它扩展了某个抽象类,该抽象类具有为识别等定义的方法。
但是,我似乎无法确定是否可以.class
从我的主包外部控制这些文件。
这可能吗?如果有怎么办?如果没有,我可以尝试其他选择吗?
谢谢!
据我了解你。你想建立一个插件系统。如果是这样,您应该考虑 java 服务提供者方法。
在这种方法中,您在主包中定义服务提供者接口 (SPI),并使用 java META-INF/services 位置来查找实现。在这种情况下,您只需将 jar 文件放在类路径中即可添加扩展。
从 java 1.6 开始,您可以使用 java.util.ServiceLoader。
或者你看看 apache 发现 http://commons.apache.org/proper/commons-discovery/apidocs/org/apache/commons/discovery/tools/Service.html。
它比 java.util.SerivceLoader 更强大,因为它允许您将构造函数参数传递给它实例化的服务。
一个可能的插件加载器实现可能如下所示:
public interface ServiceInterface {
}
public class PluginHost {
public ServiceLoader<ServiceInterface> loadPlugins() {
File[] pluginLibraries = getPluginLibraries();
URL[] pluginLibUrls = new URL[pluginLibraries.length];
for (int i = 0; i < pluginLibUrls.length; i++) {
try {
pluginLibUrls[i] = pluginLibraries[i].toURI().toURL();
} catch (MalformedURLException e) {
throw new IllegalStateException("Unable to load plugin: "
+ pluginLibraries[i], e);
}
}
URLClassLoader pluginsClassLoader = new URLClassLoader(pluginLibUrls,
ServiceInterface.class.getClassLoader());
ServiceLoader<ServiceInterface> serviceLoader = ServiceLoader.load(
ServiceInterface.class, pluginsClassLoader);
return serviceLoader;
}
private File[] getPluginLibraries() {
// please implement
}
}
这是可能的。
罐子只是压缩的类文件。
只要类文件在类路径中就可以了。
解压缩 jar 文件(从 .jar 重命名为 .zip 并解压缩)以查看 java 包的目录结构应该是什么。
有关简单的扩展机制,请查看ServiceLoader。
有关更完整的扩展机制,请查看 OSGi。