我刚刚读到 Java 9 模块系统,我想问一下ServiceLoader。当应用程序已经启动时,有什么方法可以添加服务实现吗?删除一些服务实现怎么样?
使用案例:我将有一些可以计算某些内容的应用程序。计算算法将在某些服务(Java 9模块)中定义。是否可以采取任何步骤来替换此算法而不停止应用程序?我什么时候更换罐子只是计算会失败,我需要捕获错误并在模块加载完成后重新启动?
还有其他项目可以支持这样的用例吗?
让我们假设 BankController 是您的服务。
如果您想从动态路径动态加载其实现,请创建一个新的模块层并加载实现。
private final BankController loadController(final BankConfig config) {
System.out.println("Loading bank with config : " + JSON.toJson(config));
try {
//Curent ModuleLayer is usually boot layer. but it can be different if you are using multiple layers
ModuleLayer currentModuleLayer = this.getClass().getModule().getLayer(); //ModuleLayer.boot();
final Set<Path> modulePathSet = Set.of(new File("path of implementation").toPath());
//ModuleFinder to find modules
final ModuleFinder moduleFinder = ModuleFinder.of(modulePathSet.toArray(new Path[0]));
//I really dont know why does it requires empty finder.
final ModuleFinder emptyFinder = ModuleFinder.of(new Path[0]);
//ModuleNames to be loaded
final Set<String> moduleNames = moduleFinder.findAll().stream().map(moduleRef -> moduleRef.descriptor().name()).collect(Collectors.toSet());
// Unless you want to use URLClassloader for tomcat like situation, use Current Class Loader
final ClassLoader loader = this.getClass().getClassLoader();
//Derive new configuration from current module layer configuration
final Configuration configuration = currentModuleLayer.configuration().resolveAndBind(moduleFinder, emptyFinder, moduleNames);
//New Module layer derived from current modulee layer
final ModuleLayer moduleLayer = currentModuleLayer.defineModulesWithOneLoader(configuration, loader);
//create new instance of Implementation, in this case org.util.npci.coreconnect.CoreController implements org.util.npci.api.BankController
final BankController bankController = ServiceLoader.load(moduleLayer, BankController.class);
return bankController;
} catch (Exception e) {BootLogger.info(e);}
return null;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)