在轮询目录时如何防止重复的Spring集成服务激活

在轮询目录时如何防止重复的Spring集成服务激活,spring,spring-integration,Spring,Spring Integration,我有一个Spring集成目录轮询器: <task:executor id="filePollingExecutor" pool-size="1" /> <int:channel id="inboundFilesChannel" datatype="java.io.File" /> <int-file:inbound-channel-adapter id="inboundFilesAdapter" channel="inboundFilesChannel

我有一个Spring集成目录轮询器:

<task:executor id="filePollingExecutor" pool-size="1" />
<int:channel id="inboundFilesChannel" datatype="java.io.File" />
<int-file:inbound-channel-adapter id="inboundFilesAdapter" 
      channel="inboundFilesChannel"
      directory="/my/files/queue"
      prevent-duplicates="true">
  <int:poller id="poller" fixed-delay="1000" 
              max-messages-per-poll="1" 
              task-executor="filePollingExecutor" />
</int-file:inbound-channel-adapter>

为了响应目录中出现的文件,我有一个服务激活器,它调用服务上的一个方法:

不幸的是,我发现当文件到达时,服务总是被调用两次。最初我认为这是因为有多个执行器线程,但您可能会注意到,我试图通过将轮询器绑定到池大小为1的taskExecutor来解决这个问题

我发现我可以通过增加两次投票之间的延迟来解决这个问题。我认为关键在于它比处理文件所需的时间要长

<int:poller id="poller" fixed-delay="10000" 
            max-messages-per-poll="100" 
            task-executor="filePollingExecutor" />

然而,这感觉像是一个混乱,而不是修复

我是否缺少一些应用于防止重复的配置


可能值得注意的是,我确实尝试过使用
nio-locker
,但问题是,处理过程中的一部分涉及发送一封附有文件的电子邮件。文件锁定阻止了该操作,因为在锁定期间文件不再可读。

此答案基于Gary Russell在上述评论中的提示

双重处理文件的原因是,root和web配置都在初始化文件系统侦听器,因此每个文件都要处理两次

我避免在多个上下文中使用文件侦听器的方法如下

首先定义一个web配置,它只拾取“web”包下的类

创建单独的根配置,只加载不在“web”包中的bean。i、 e

@Configuration
@ComponentScan(basePackages = { "com.myapp.services" })
public class ServicesConfig {
}

配置中的另一个因素需要花一点时间才能解决,那就是我的servlet过滤器和web安全配置需要在“根”上下文而不是web上下文中。

首先
fixed delay=“1”
os坏了。它真的应该至少在1秒左右。当同一文件被发送到
inboundFilesChannel
两次时,请显示日志(org.springframework.integration的调试级别)。Cheesno op.我们刚刚根据您的配置编写了一个测试用例,每个文件只处理一次。下游出现问题,而不是文件轮询器…>>不幸的是,我发现当文件到达时,服务始终被调用两次。-这是否在web应用程序中运行?一个常见的错误是在servlet和根应用程序上下文中加载SI配置,所以实际上有两个适配器在做同样的事情。这是我的配置示例版本中的一个输入错误-我看到这个延迟为1000毫秒。但是,您是对的,它位于web应用程序容器中。我没有web.xml,只有
@Configuration
@EnableWebMvc
以及
@ComponentScan
。我还可以看到我的
DispatcherServletInitializer
正在
getRootConfigClasses()
getServletConfigClasses()
中加载该配置类。我认为应该确保servlet上下文没有加载导入我的
spring integration context.xml
的config类,这对吗?
@Configuration
@ComponentScan(basePackages = { "com.myapp.services" })
public class ServicesConfig {
}