在应用程序上下文启动后在spring中执行任务,以便任务失败不会影响应用程序启动

时间:2018-03-26 08:28:15

标签: spring

我有一个任务,我需要在春季应用程序启动时执行(上下文启动)。 有些情况下该任务可能会失败(数据可能没有准备好)并导致应用程序开始失败。我的问题是:

  1. 最好的方法是什么,以便任务成功/失败不会影响开始?注意:案例是我们必须在上下文启动后至少运行一次任务?

3 个答案:

答案 0 :(得分:3)

您可以创建一个spring组件来侦听spring context started事件。像这样:

@Component
public class SpringCtxListener {

    @EventListener
    public void checkUser(ContextRefreshedEvent cre) throws Exception
    {
        //This method is called when Spring context has started and here you can execute your task
    }
}

安吉洛

答案 1 :(得分:1)

@Angelo提供的功能也可以。 我要跟随。完成上下文刷新/启动后将执行此任务  @Scheduled(cron="*/5 * * * * MON-FRI") public void doSomething() { // something that should execute on weekdays only }

注意:要求改变了一点,我必须每天至少做一次这样的任务,因此使用@Scheduled

答案 2 :(得分:0)

有点hacky,但可能会做到这一点:

@Component
public class SomeBean {

    @PostConstruct
    public void doTask() {
       int i = 0;
        try {
            doTheTask();
        } catch (final Exception e) {
            if (i == 10) {
                throw new RuntimeException(e);
            }
            Thread.sleep(200);
            i++;
        }
    }
}

这将在放弃之前运行任务10次,每次尝试之间等待200ms。请注意,如果使用此处处于休眠状态的相同线程来准备数据,则无法提供帮助,您必须将任务的运行放在单独的线程中。

另一种可能性是使用Spring的{​​{1}}:

首先,您需要启用计划。这可以通过java配置中的@Scheduled或某些xml:

来完成
@EnableScheduling

接下来,使用<task:scheduled-tasks scheduler="myScheduler"> <task:scheduled ref="myBean" method="printMessage" fixed-delay="5000" /> </task:scheduled-tasks> <task:scheduler id="myScheduler"/> 注释方法:

@Scheduled

请注意,仍然无法保证任务实际成功。您可以将它@Scheduled(initialDelay= 600000) //ms, =10 minutes public void doTask() { doTheTask(); } 组合起来多次运行它,但请注意,抛出该方法的任何异常都将暂停执行一系列。对于更有保障的运行方法,这样的事情应该有效(虽然成功时抛出异常看起来有点奇怪......)

fixedDelay