code: private static List<String> loadAndWatchDir(Path path, ResourceLoader resourceLoader, String resourcePaths) {
          final List<String> result = new ArrayList<>();
          try {
              Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                  @Override
                  public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                          throws IOException {
                      result.addAll(load(file.toAbsolutePath().toString()));
                      return FileVisitResult.CONTINUE;
                  }
              });
          } catch (IOException ex) {
              LOGGER.error("加载资源失败："+path, ex);
          }
          DirectoryWatcher.WatcherCallback watcherCallback = new DirectoryWatcher.WatcherCallback(){
  
              private long lastExecute = System.currentTimeMillis();
              @Override
              public void execute(WatchEvent.Kind<?> kind, String path) {
                  //一秒内发生的多个相同事件认定为一次，防止短时间内多次加载资源
                  if(System.currentTimeMillis() - lastExecute > 1000){
                      lastExecute = System.currentTimeMillis();
                      LOGGER.info("事件："+kind.name()+" ,路径："+path);
                      synchronized(AutoDetector.class){
                          DirectoryWatcher dw = WATCHER_CALLBACKS.get(this);
                          String paths = RESOURCES.get(dw);
                          ResourceLoader loader = RESOURCE_LOADERS.get(dw);
                          LOGGER.info("重新加载数据");
                          loadAndWatch(loader, paths);
                      }
                  }
              }
  
          };
          DirectoryWatcher directoryWatcher = DirectoryWatcher.getDirectoryWatcher(watcherCallback,
                  StandardWatchEventKinds.ENTRY_CREATE,
                      StandardWatchEventKinds.ENTRY_MODIFY,
                      StandardWatchEventKinds.ENTRY_DELETE);
          directoryWatcher.watchDirectoryTree(path);
  
          WATCHER_CALLBACKS.put(watcherCallback, directoryWatcher);
          RESOURCES.put(directoryWatcher, resourcePaths);
          RESOURCE_LOADERS.put(directoryWatcher, resourceLoader);
  
          return result;
      }
docs: 递归加载目录下面的所有资源
  并监控目录变化
  @param path 目录路径
  @param resourceLoader 资源自定义加载逻辑
  @param resourcePaths 资源的所有路径，用于资源监控
  @return 目录所有资源内容