如何通过布尔标志控制Spring Integration SFTP入站适配器的轮询?
如何用布尔标志控制Spring Integration SFTP适配器的轮询行为?
当然可以,Spring Integration提供了多种简洁的方案来实现这个需求,以下是几种常用的实现方式:
方案一:使用ConditionalPollerAdvice(推荐)
这是Spring Integration专门提供的条件轮询增强器,能直接控制轮询是否执行:
- 定义一个线程安全的布尔标志Bean:
@Bean public AtomicBoolean sftpPollingEnabled() { return new AtomicBoolean(true); // 默认开启轮询 }
- 创建
ConditionalPollerAdvice,绑定判断逻辑:
@Bean public ConditionalPollerAdvice sftpPollingAdvice(AtomicBoolean sftpPollingEnabled) { ConditionalPollerAdvice advice = new ConditionalPollerAdvice(); // 轮询前判断标志,返回true则执行轮询,false则跳过 advice.setCondition(context -> sftpPollingEnabled.get()); return advice; }
- 配置SFTP入站适配器时,将增强器添加到轮询器的通知链中:
@Bean public IntegrationFlow sftpInboundFlow(SftpRemoteFileTemplate sftpTemplate, ConditionalPollerAdvice sftpPollingAdvice, AtomicBoolean sftpPollingEnabled) { return IntegrationFlow.from(Sftp.inboundAdapter(sftpTemplate) .remoteDirectory("/remote/sftp/path") .localDirectory(new File("/local/storage/path")), e -> e.poller(Pollers.fixedDelay(5000) // 基础轮询间隔5秒 .advice(sftpPollingAdvice))) .handle(message -> { // 处理下载后的文件逻辑 File file = (File) message.getPayload(); System.out.println("处理文件:" + file.getName()); }) .get(); }
方案二:自定义Trigger控制轮询时机
如果需要更灵活的轮询触发逻辑,可以自定义Trigger,根据标志动态调整下一次轮询时间:
@Bean public Trigger sftpPollTrigger(AtomicBoolean sftpPollingEnabled) { return context -> { if (!sftpPollingEnabled.get()) { // 标志为false时,返回极远的未来时间,暂停轮询 return new Date(Long.MAX_VALUE); } // 标志为true时,按5秒间隔触发轮询 return new Date(System.currentTimeMillis() + 5000); }; }
配置轮询器使用该Trigger:
e -> e.poller(Pollers.trigger(sftpPollTrigger)))
方案三:代理MessageSource控制文件获取
通过包装SFTP的MessageSource,在文件获取环节判断标志:
@Bean public MessageSource<File> sftpMessageSource(SftpRemoteFileTemplate sftpTemplate, AtomicBoolean sftpPollingEnabled) { // 原生SFTP消息源 SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(new SftpInboundFileSynchronizer(sftpTemplate)); source.setRemoteDirectory("/remote/sftp/path"); source.setLocalDirectory(new File("/local/storage/path")); // 包装成代理,控制是否执行文件获取 return new MessageSource<>() { @Override public Message<File> receive() { return sftpPollingEnabled.get() ? source.receive() : null; } }; }
然后在IntegrationFlow中使用这个代理的MessageSource即可。
额外说明
- 必须使用线程安全的布尔类型(如
AtomicBoolean),避免多线程环境下的标志状态不一致问题。 - 如果是Spring Boot环境,可将标志绑定到外部配置(如
application.properties中的sftp.polling.enabled=true),通过@Value或@ConfigurationProperties注入,实现动态修改配置控制轮询。
内容的提问来源于stack exchange,提问作者Choff
相关产品推荐
相关产品推荐

