本文共 2787 字,大约阅读时间需要 9 分钟。
对于我们自己封装的spi来说,我们可能希望他实现类似于插件的功能,例如你有一个汽车工厂,你目前有提供小汽车,如果你希望他动态支持卡车,公交车,那么spi可以帮你实现这个功能,对于我实现这个SPI功能主要由以下几个步骤组成。
/** * 目录监控. * * @param path */ public static void watchDir(String path) { initClassLoader(path); try (WatchService watchService = FileSystems.getDefault().newWatchService()) { //给path路径加上文件观察服务 Paths.get(path).register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE); while (true) { final WatchKey key = watchService.take(); for (WatchEvent watchEvent : key.pollEvents()) { final WatchEvent.Kind kind = watchEvent.kind(); if (kind == StandardWatchEventKinds.OVERFLOW) { continue; } final WatchEventwatchEventPath = (WatchEvent ) watchEvent; final Path filename = watchEventPath.context(); System.out.println(kind + " -> " + filename); initClassLoader(path); } boolean valid = key.reset(); if (!valid) { break; } } } catch (IOException | InterruptedException ex) { System.err.println(ex); } }
static void initClassLoader(String path) { for (File file : FileUtil.loopFiles(path)) { System.out.println("load jar:" + file.getName()); URL url = file.toURI().toURL(); DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(new URL[]{url}, ClassLoader.getSystemClassLoader()); dynamicClassLoaders.add(dynamicClassLoader); } }
/** * 返回所有具体的providerFactory工厂,使用dynamicClassLoaders加载器 * * @param clazz * @param * @return */ public static List getProviderFactory(Class clazz) { List list = new ArrayList<>(); for (ClassLoader classLoader : dynamicClassLoaders) { ServiceLoader load = ServiceLoader.load(clazz, classLoader); ListidList = list.stream().map(o -> o.getId()).collect(Collectors.toList()); for (U providerFactory : load) { if (!idList.contains(providerFactory.getId())) { list.add(providerFactory); } } } return list; }
@SneakyThrows @GetMapping("hello") public ResponseEntity hello() { Listresult = new ArrayList<>(); for (ProviderFactory u : SpiFactory.getProviderFactory(ProviderFactory.class)) { result.add(u.create().login()); } return ResponseEntity.ok(result); }
结果
转载地址:http://cvkki.baihongyu.com/