博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spi~动态监控目录的jar实现热加载
阅读量:3965 次
发布时间:2019-05-24

本文共 2787 字,大约阅读时间需要 9 分钟。

对于我们自己封装的spi来说,我们可能希望他实现类似于插件的功能,例如你有一个汽车工厂,你目前有提供小汽车,如果你希望他动态支持卡车,公交车,那么spi可以帮你实现这个功能,对于我实现这个SPI功能主要由以下几个步骤组成。

  1. 对文件夹目录的监控
  2. 对文件夹里jar也的装载,动态类加载器机制实现
  3. 通过类型名称,返回实现类的列表

具体实现

目录监控

/**     * 目录监控.     *     * @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 WatchEvent
watchEventPath = (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); List
idList = list.stream().map(o -> o.getId()).collect(Collectors.toList()); for (U providerFactory : load) { if (!idList.contains(providerFactory.getId())) { list.add(providerFactory); } } } return list; }

程序调用

1

@SneakyThrows    @GetMapping("hello")    public ResponseEntity hello() {        List
result = new ArrayList<>(); for (ProviderFactory u : SpiFactory.getProviderFactory(ProviderFactory.class)) { result.add(u.create().login()); } return ResponseEntity.ok(result); }

结果

2

转载地址:http://cvkki.baihongyu.com/

你可能感兴趣的文章
比较字符串
查看>>
Java EE 精萃
查看>>
Open Source 精萃
查看>>
Java EE 简介
查看>>
Weblogic 简介
查看>>
观察者模式 (Observer)
查看>>
Java 集合框架
查看>>
Weblogic 精萃
查看>>
Servlet 精萃
查看>>
Servlet 简介
查看>>
Spring 环境设置
查看>>
XStream 精萃
查看>>
XStream 环境设置
查看>>
XStream 例子: Hello World
查看>>
XStream 自定义标签
查看>>
Git 分支
查看>>
Git 冲突
查看>>
Git Merging vs. Rebasing
查看>>
Git 与 Eclipse 整合
查看>>
Kafka 发送消息 Idempotent
查看>>