我有一个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
,但问题在于,部分处理涉及发送附有文件的电子邮件。文件锁阻止了这样做,因为文件在锁定期间不再可读。
答案 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上下文。