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

时间:2014-08-07 13:51:42

标签: spring spring-integration

我有一个Spring Integration目录轮询器:

<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" />

然而,这感觉就像是一种kludge而不是修复。

我是否遗漏了一些我应该用来防止重复的配置?

值得注意的是,我确实尝试使用nio-locker,但问题在于,部分处理涉及发送附有文件的电子邮件。文件锁阻止了这样做,因为文件在锁定期间不再可读。

1 个答案:

答案 0 :(得分:1)

这个答案基于Gary Russell在上述评论中的提示。

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

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

首先定义一个只接受“web”包下的类的Web配置。

@Configuration
@ComponentScan(basePackages = { "com.myapp.web" })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

创建单独的根配置,仅加载不在“web”包中的bean。即。

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

配置需要一段时间才能解决的另一个因素是我的servlet过滤器和Web安全配置需要位于“根”上下文而不是Web上下文。