4 回答

TA貢獻(xiàn)1911條經(jīng)驗(yàn) 獲得超7個(gè)贊
基本思想也是...
讀取特定目錄中的所有文件
將每個(gè)結(jié)果的引用轉(zhuǎn)換為
File
URL
使用與結(jié)果一起設(shè)定種子的 ,加載每個(gè)結(jié)果
URLClassLoader
URL
用于查找具有特定名稱的所有匹配資源
URLClassLoader#findResources
迭代匹配的資源并加載每個(gè)資源,這至少應(yīng)該給出“入口點(diǎn)”類名
裝入由“入口點(diǎn)”屬性指定的類
例如。。。
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:我沒有運(yùn)行這個(gè),但這是“基本”

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超2個(gè)贊
Java已經(jīng)有一個(gè)這樣的類:服務(wù)加載器。
服務(wù)加載器類是隨 Java 6 引入的,但“SPI jar”概念實(shí)際上與 Java 1.3 一樣古老。這個(gè)想法是每個(gè)jar都包含一個(gè)簡(jiǎn)短的文本文件,該文件描述了其特定服務(wù)提供者接口的實(shí)現(xiàn)。
例如,如果一個(gè).jar文件包含兩個(gè)名為 FooPlugin 和 BarPlugin 的 BasePlugin 子類,則該.jar文件還將包含以下條目:
META-INF/services/com.example.BasePlugin
該 jar 條目將是一個(gè)文本文件,包含以下行:
com.myplugins.FooPlugin
com.myplugins.BarPlugin
您的項(xiàng)目將通過創(chuàng)建一個(gè)從目錄中讀取的類加載器來掃描插件: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 的另一個(gè)優(yōu)點(diǎn)是,您的代碼將能夠與模塊一起使用,這是 Java 9 引入的更完整的代碼封裝形式,可提供更高的安全性。

TA貢獻(xiàn)1779條經(jīng)驗(yàn) 獲得超6個(gè)贊
這里有一個(gè)例子,它可能會(huì)有所幫助。另外,你應(yīng)該看看OSGi。
添加回答
舉報(bào)