gpt4 book ai didi

java - 有没有办法在不更新主应用程序的情况下更新模块化库?

转载 作者:行者123 更新时间:2023-12-02 05:35:36 24 4
gpt4 key购买 nike

在模块化应用程序组织之前,我有一个主要的 JavaFX 应用程序,它加载自定义创建的多个库,以实现主应用程序中的不同选项和可能性。

在旧的实现方式中,我只是发送新的库进行更新,主应用程序从文件夹中读取所有库,它的工作方式就像一个魅力。但是在模块化系统中,如果我的应用程序想要使用我发送的新模块化库,它需要更新其模块信息文件,因此我需要发送模块化库和主应用程序的更新。想象一下,Chrome 需要为创建的每个新插件发送浏览器更新。正如我所看到的,使用 Java 模块化系统您无法创建模块化应用程序。

有没有办法导入新模块而不更新主应用程序或其他方法?

最佳答案

Java 有一个类:ServiceLoader .

如果我们假设您有一个名为 PluginProvider 的“服务提供者”接口(interface),其他模块可以通过将其放入各自的 module-info.java 描述符中来声明自己提供该服务:

provides com.john.myapp.PluginProvider with com.library.MyProvider;

然后,您的应用程序会声明它在自己的模块信息中使用该服务:

uses com.john.myapp.PluginProvider;

您的应用程序代码将创建一个 ModuleFinder它会在您期望这些插件模块驻留的目录(或多个目录)中查找,然后将该 ModuleFinder 传递给 Configuration可用于创建 ModuleLayer对于服务加载器:

public class PluginLoader {

private final ServiceLoader<PluginProvider> loader;

public PluginLoader() {

Path pluginDir = Paths.get(System.getProperty("user.home"),
".local", "share", "MyApplication", "plugins");

ModuleLayer layer = PluginProvider.class.getModule().getLayer();
layer = layer.defineModulesWithOneLoader(
layer.configuration().resolveAndBind(
ModuleFinder.of(),
ModuleFinder.of(pluginDir),
Collections.emptySet()),
PluginProvider.class.getClassLoader());

loader = ServiceLoader.load(layer, PluginProvider.class);
}

public Stream<PluginProvider> getAll() {
return loader.stream();
}

public void reload() {
loader.reload();
}
}

您甚至可能想要watch新文件或已删除文件的插件目录:

try (WatchService watch = pluginDir.getFileSystem().newWatchService()) {

pluginDir.register(watch,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.OVERFLOW);

WatchKey key;
while ((key = watch.take()).isValid()) {
loader.reload();
key.reset();
}
}

关于java - 有没有办法在不更新主应用程序的情况下更新模块化库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56169439/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com