You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何关闭FileReadingMessageSource.WatchServiceDirectoryScanner子目录递归扫描?

你使用的Spring Integration 5.3.x版本中,WatchServiceDirectoryScanner默认实现就是递归监听根目录下所有子目录的文件事件,框架本身没有提供直接关闭递归监听的配置属性,你可以根据场景选择以下两种实现方案:

方案1:仅过滤子目录文件(实现成本最低)

如果不需要取消子目录的监听注册,只是不处理子目录下的文件,只需要在现有ChainFileListFilter链的最前面加一个根目录路径过滤器即可。
你可以写一个简单的自定义过滤器:

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.integration.file.filters.FileListFilter;

public class RootDirOnlyFileFilter implements FileListFilter<File> {
    private File rootDir;

    @Override
    public List<File> filterFiles(File[] files) {
        return Arrays.stream(files)
                .filter(file -> rootDir.equals(file.getParentFile()))
                .collect(Collectors.toList());
    }

    public void setRootDirPath(String rootDirPath) {
        this.rootDir = new File(rootDirPath);
    }
}

然后把这个过滤器加到你的过滤器链最前面:

<bean id="channelFilter" class="org.springframework.integration.file.filters.ChainFileListFilter">
  <constructor-arg>
    <list>
      <!-- 新增的根目录过滤器放在最前面 -->
      <bean class="com.yourpackage.RootDirOnlyFileFilter">
        <property name="rootDirPath" value="${channel.dir}" />
      </bean>
      <bean class="org.springframework.integration.file.filters.SimplePatternFileListFilter">
        <constructor-arg value="SpreadSheets*.xls" />
      </bean>
      <bean id="filter" class="org.springframework.integration.file.filters.LastModifiedFileListFilter">
        <property name="age" value="${channel.filter.age}" />
      </bean>
      <ref bean="persistentFilter" />
    </list>
  </constructor-arg>
</bean>

所有子目录下的文件都会被直接过滤,不会进入后续处理流程。

方案2:自定义扫描器,彻底取消子目录监听

如果需要避免注册多余的子目录监听,你可以继承WatchServiceDirectoryScanner,重写监听注册逻辑,只注册根目录:

import java.nio.file.Path;
import org.springframework.integration.file.WatchServiceDirectoryScanner;

public class NonRecursiveWatchScanner extends WatchServiceDirectoryScanner {
    @Override
    protected void registerWatch(Path directory) {
        // 仅注册配置的根目录,不递归处理子目录
        if (directory.equals(getDirectory())) {
            super.registerWatch(directory);
        }
    }
}

然后配置自定义扫描器,替换适配器的默认扫描器:

<!-- 自定义无递归扫描器 -->
<bean id="nonRecursiveScanner" class="com.yourpackage.NonRecursiveWatchScanner">
  <property name="directory" value="${channel.dir}"/>
  <property name="filter" ref="channelFilter"/>
</bean>

<!-- 修改入站适配器配置,去掉use-watch-service属性,引入自定义扫描器 -->
<int-file:inbound-channel-adapter id="channelIn" directory="${channel.dir}" auto-create-directory="false" scanner="nonRecursiveScanner" watch-events="CREATE,MODIFY">
  <int-file:nio-locker ref="channelLocker"/>
  <int:poller fixed-delay="${channel.polling.delay}" max-messages-per-poll="${channel.polling.maxmsgs}"></int:poller>
</int-file:inbound-channel-adapter>

配置完成后,框架只会监听指定根目录的文件事件,不会再注册子目录的监听。

内容的提问来源于stack exchange,提问作者Kode Charlie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:24:06