中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

spi~動態監(jian)控目錄的(de)jar實現(xian)熱(re)加載

對于我(wo)們自己封裝的(de)spi來說,我(wo)們可能希望他實現類似于插件的(de)功(gong)(gong)能,例(li)如你有(you)一個(ge)汽(qi)車(che)(che)工(gong)廠,你目前有(you)提供小汽(qi)車(che)(che),如果你希望他動態支(zhi)持卡(ka)車(che)(che),公交車(che)(che),那(nei)么spi可以幫你實現這(zhe)個(ge)功(gong)(gong)能,對于我(wo)實現這(zhe)個(ge)SPI功(gong)(gong)能主要由(you)以下幾個(ge)步(bu)驟組成。

  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<Path> watchEventPath = (WatchEvent<Path>) 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 <U>
     * @return
     */
    public static <U extends ProviderFactory> List<U> getProviderFactory(Class<U> clazz) {
        List<U> list = new ArrayList<>();
        for (ClassLoader classLoader : dynamicClassLoaders) {
            ServiceLoader<U> load = ServiceLoader.load(clazz, classLoader);
            List<String> 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<String> result = new ArrayList<>();
        for (ProviderFactory u : SpiFactory.getProviderFactory(ProviderFactory.class)) {
            result.add(u.create().login());
        }
        return ResponseEntity.ok(result);
    }

結果
2

posted @ 2021-02-18 10:23  張占嶺  閱讀(730)  評論(0)    收藏  舉報