如何在Spring TaskExecutor中重试

时间:2013-01-01 13:56:38

标签: java spring scheduled-tasks

按照我使用Spring 3 TaskExecutor发送的异步邮件的代码。代码工作正常,我只想知道任何邮件是否因任何原因无法发送,然后必须再次添加到队列中并且必须重新发送。

我使用Google搜索,但没有获得重试政策的信息。

帮助将受到高度赞赏!!!

@Service
public class AsyncMailSender implements MailSender {

    /* Logger for Search-Controller Class */
    public static final Logger LOGGER = Logger.getLogger(AsyncMailSender.class);

    @Autowired
    private MailSender mailSender;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private VelocityEngine velocityEngine;

    public void send(SimpleMailMessage simpleMessage) throws MailException {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        modelMap.put("user", "Manoj");
        simpleMessage.setText(VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "templates/email.vm", modelMap));
        taskExecutor.execute(new AsyncMailTask(simpleMessage));
    }

    public void send(SimpleMailMessage[] simpleMessages) throws MailException {
        for (SimpleMailMessage message : simpleMessages) {
            send(message);
        }
    }

    private class AsyncMailTask implements Runnable {

        private SimpleMailMessage message;

        private AsyncMailTask(SimpleMailMessage message) {
            this.message = message;
        }

        public void run() {
            LOGGER.info("Sending Emails" + message.getSubject());
            mailSender.send(message);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

AFAIK,目前无法使用Spring 3 TaskExecutor配置重试,有一个SPR与之关联。话虽如此,我认为如果抛出任何异常,Spring会自动重试该方法。如果异常继续发生,这可能会对您造成问题(就资源消耗而言)。

答案 1 :(得分:2)

这可能不太理想,但您可以在任务中使用Spring-Retry,如下所示:

@Service
public class AsyncMailSender implements MailSender {

    @Autowired
    RetryTemplate retryTemplate;

    private class AsyncMailTask implements Runnable {

        private SimpleMailMessage message;

        private AsyncMailTask(SimpleMailMessage message) {
            this.message = message;
        }

        public void run() {
            retryTemplate.execute(new RetryCallback<Void, PersistenceException>() {

                    LOGGER.info("Sending Emails" + message.getSubject());
                    mailSender.send(message);

                    return null;
                }
            });

        }
    }

您可以像这样配置RetryTemplate:

@Configuration
public class RetryConfiguration {

    @Bean 
    RetryTemplate retryTemplate() {

        RetryTemplate template = new RetryTemplate();

        TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
        policy.setTimeout(30000L);

        template.setRetryPolicy(policy);

        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        template.setBackOffPolicy(backOffPolicy);

        return template;
    }
}

您可能还会发现Spring-Batch有用。

答案 2 :(得分:0)

Spring并没有为您做到这一点

您必须自己进行异常处理和排队。 TaskExecutor本身具有固有的重试能力,因为它只是在下一个配置的时间间隔运行您的任务而不管是什么。