4 回答
TA贡献1911条经验 获得超7个赞
基本思想也是...
读取特定目录中的所有文件
将每个结果的引用转换为
File
URL
使用与结果一起设定种子的 ,加载每个结果
URLClassLoader
URL
用于查找具有特定名称的所有匹配资源
URLClassLoader#findResources
迭代匹配的资源并加载每个资源,这至少应该给出“入口点”类名
装入由“入口点”属性指定的类
例如。。。
public List<PluginClass> loadPlugins() throws MalformedURLException, IOException, ClassNotFoundException {
File plugins[] = new File("./Plugins").listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.getName().endsWith(".jar");
}
});
List<URL> plugInURLs = new ArrayList<>(plugins.length);
for (File plugin : plugins) {
plugInURLs.add(plugin.toURI().toURL());
}
URLClassLoader loader = new URLClassLoader(plugInURLs.toArray(new URL[0]));
Enumeration<URL> resources = loader.findResources("/META-INFO/Plugin.properties");
List<PluginClass> classes = new ArrayList<>(plugInURLs.size());
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
Properties properties = new Properties();
try (InputStream is = resource.openStream()) {
properties.load(is);
String className = properties.getProperty("enrty-point");
PluginClass pluginClass = loader.loadClass(className);
classes.add(pluginClass);
}
}
return classes
}
nb:我没有运行这个,但这是“基本”
TA贡献1804条经验 获得超2个赞
Java已经有一个这样的类:服务加载器。
服务加载器类是随 Java 6 引入的,但“SPI jar”概念实际上与 Java 1.3 一样古老。这个想法是每个jar都包含一个简短的文本文件,该文件描述了其特定服务提供者接口的实现。
例如,如果一个.jar文件包含两个名为 FooPlugin 和 BarPlugin 的 BasePlugin 子类,则该.jar文件还将包含以下条目:
META-INF/services/com.example.BasePlugin
该 jar 条目将是一个文本文件,包含以下行:
com.myplugins.FooPlugin
com.myplugins.BarPlugin
您的项目将通过创建一个从目录中读取的类加载器来扫描插件:plugins
Collection<URL> urlList = new ArrayList<>();
Path pluginsDir = Paths.get(
System.getProperty("user.home"), "plugins");
try (DirectoryStream<Path> jars =
Files.newDirectoryStream(pluginsDir, "*.jar")) {
for (Path jar : jars) {
urlList.add(jar.toUri().toURL());
}
}
URL[] urls = urlList.toArray(new URL[0]);
ClassLoader pluginClassLoader = new URLClassLoader(urls,
BasePlugin.class.getClassLoader());
ServiceLoader<BasePlugin> plugins =
ServiceLoader.load(BasePlugin.class, pluginClassLoader);
for (BasePlugin plugin : plugins) {
plugin.onEnable();
// etc.
}
使用 ServiceLoader 的另一个优点是,您的代码将能够与模块一起使用,这是 Java 9 引入的更完整的代码封装形式,可提供更高的安全性。
添加回答
举报