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 引入的更完整的代碼封裝形式,可提供更高的安全性。
添加回答
舉報