为POP3访问配置的Spring Integration Mail入站通道适配器将同一个电子邮件拉两次

时间:2015-07-15 15:17:54

标签: spring-integration

我有一个Spring Integration Mail入站适配器,配置为轮询POP3电子邮件收件箱,以处理带有大型XML文件附件的传入电子邮件。配置如下:

    <int:channel id="emailInputChannel"/> 
    <int-mail:inbound-channel-adapter id="pop3EmailAdapter" store-uri="pop3://${pop3.user}:${pop3.pwd}@${pop3.server.host}/Inbox" 
    channel="emailInputChannel" should-delete-messages="true" auto-startup="true" java-mail-properties="javaMailProperties">               
<int:poller max-messages-per-poll="1" fixed-rate="${email.poller.rate}" />
    </int-mail:inbound-channel-adapter>

    <!-- Java Mail POP3 properties -->
    <util:properties id="javaMailProperties">
      <beans:prop key="mail.debug">true</beans:prop> 
      <beans:prop key="mail.pop3.port">${pop3.server.port}</beans:prop> 
    </util:properties>

使用此配置,我注意到默认情况下适配器使用多个任务调度程序(本质上是轮询器)。因此,即使我已经指出在使用should-delete-message =&#34; true&#34;提取后需要删除电子邮件,也会多次收到相同的电子邮件。轮询率设置为120秒。下面的日志显示相同的电子邮件在2秒内被拾取

 07-15-2015 05:41:46,817 INFO [task-scheduler-7] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

07-15-2015 05:51:45,455 INFO [task-scheduler-10] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

 07-15-2015 05:51:46,994 INFO [task-scheduler-4] AbstractMailReceiver:receive:229 | attempting to receive mail from folder [Inbox]

 07-15-2015 05:51:47,655 INFO [task-scheduler-10] EmailAttachmentSplitter:extractEmailAttachments:53 | EmailAttachmentSplitter.extractEmailAttachments: Received Message with Payload javax.mail.internet.MimeMessage@15e8cbba

 07-15-2015 05:51:49,707 INFO [task-scheduler-4] EmailAttachmentSplitter:extractEmailAttachments:53 | EmailAttachmentSplitter.extractEmailAttachments: Received Message with Payload javax.mail.internet.MimeMessage@15ef73f6

有没有办法限制适配器只使用一个轮询器而不是默认的多个轮询器?如果是这样,请提供一个如何使用一个轮询器设置入站邮件适配器的示例。

1 个答案:

答案 0 :(得分:0)

fixed-delay适合您。来自PeriodicTrigger JavaDocs:

 * To measure the interval between the
 * scheduled <emphasis>start</emphasis> time of each execution instead, set the
 * 'fixedRate' property to {@code true}.

其源代码:

@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
    if (triggerContext.lastScheduledExecutionTime() == null) {
        return new Date(System.currentTimeMillis() + this.initialDelay);
    }
    else if (this.fixedRate) {
        return new Date(triggerContext.lastScheduledExecutionTime().getTime() + this.period);
    }
    return new Date(triggerContext.lastCompletionTime().getTime() + this.period);
}

由于TaskScheduler依赖于日程安排任务的日期,因此您只能使用single-thread达到fixed-delay要求。并且下一轮投票任务将在前一轮完成之后启动。