应用程序上下文开始后,在春季执行任务,这样任务故障不会影响应用程序的开始



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

  1. 最好的方法是什么,以使任务成功/失败不会影响开始?注意:情况是,我们必须在上下文开始后一次运行一次任务吗?

您可以为春季上下文开始事件创建弹簧组件侦听。这样的东西:

@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
    }
}

angelo

@angelo提供的也可以工作。我要跟随。在上下文刷新/开始完成后将运行此任务。
@Scheduled(cron="*/5 * * * * MON-FRI") public void doSomething() { // something that should execute on weekdays only }

注意:一旦使用@scheduled

有点骇人听闻,但可能会解决:

@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@Scheduled

首先,您需要启用调度。这是由@EnableScheduling在您的Java配置中完成的,也可以使用一些XML:

<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以多次运行,但是请注意,该方法中抛出的任何例外都会停止一系列执行。为了获得更保证的跑步,类似的事情应该有效(不过,在成功上抛出例外看起来有些奇怪。(

//numbers in ms, 10 minutes before the first run, then a new attempt every minute
@Scheduled(initialDelay= 600000, fixedDelay = 60000) 
public void doTask() {
   try {
      doTheTask();
   } catch (final Exception e) {
       //do nothing, retry in 1 minute
       return;
   }
   trow new AbortScheduledException("Task complete"); //made up exception with descriptive name..
}

最新更新