2016-12-16 66 views
1

我有一个计划在春季的工作,我从我的数据库中得到它的cron。每次执行时,下一个执行时间都会更新。所以,如果它被配置为每10分钟运行一次,我可以将该值更改为数据库以每15分钟计划一次该作业。春季更新调度程序

问题是我必须等待执行才能获得更新的cron:如果每15分钟计划一次作业,并且我希望将此值更改为每2分钟一次,则必须等待下一次执行(最多15分钟)每2分钟完成一次这项工作。

更新数据库后,有没有办法让这项工作重新安排?

我想销毁并刷新这个bean,但它不工作(也许这是不可能的或者在我的实现中出现错误)。也许有办法触发一个事件来执行方法configureTask。

这里是我的预定工作的片段。

@EnableScheduling 
@Component 
public class MyClass implements SchedulingConfigurer { 

    private static final String JOB = "My personal task"; 

    @Autowired 
    JobRepository jobRepository; 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 
     scheduledTaskRegistrar.addTriggerTask(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println("Hello World!"); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB); // read from database 
       String cron = byJobNameIgnoreCase.getCrontab(); 
       CronTrigger trigger = new CronTrigger(cron); 
       return trigger.nextExecutionTime(triggerContext); 
      } 
     }); 
    } 

} 
+0

我发现这个链接,但它不工作.. [http://stackoverflow.com/questions/39152599/interrupt-spring-scheduler-task-before-next-invocation?rq=1] –

回答

0

要管理这一点,我创建了一个SchedulerOrchestrator,管理我的工作。作业包含一个SchedulerFuture。

这里的代码,我希望可以帮助别人。

让我们先从这将通过我的工作来实现的接口:

public interface SchedulerObjectInterface {  
    void start(); 
    void stop(); 
} 

每个工作需要的ScheduledFuture停下来,需要一个自动装配到的TaskScheduler安排。在这里,人们工作的样本(您可以根据需要创建尽可能多的):

@Component 
public class MyFirstJob implements SchedulerObjectInterface { 

    private static final Logger log = LoggerFactory.getLogger(MyFirstJob.class); 

    public static final String JOB = "MyFirstJob"; 

    @Autowired 
    JobRepository jobRepository; 

    private ScheduledFuture future; 

    @Autowired 
    private TaskScheduler scheduler; 


    @Override 
    public void start() { 
     future = scheduler.schedule(new Runnable() { 
      @Override 
      public void run() { 
       System.out.println(JOB + " Hello World! " + new Date()); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       String cron = cronConfig(); 
       System.out.println(cron); 
       CronTrigger trigger = new CronTrigger(cron); 
       return trigger.nextExecutionTime(triggerContext); 
      } 
     }); 

    } 

    @Override 
    public void stop() { 
     future.cancel(false); 
    } 

    // retrieve cron from database 
    private String cronConfig() { 
     JobScheduled byJobNameIgnoreCase = jobRepository.findByJobNameIgnoreCase(JOB); 
     return byJobNameIgnoreCase.getCrontab(); 
    } 

} 

最后,我们可以增加我们的工作到一个协调器:

@Configuration 
public class SchedulerOrchestrator { 

    private static final Logger log = LoggerFactory.getLogger(SchedulerOrchestrator.class); 

    private static Map<String, SchedulerObjectInterface> schduledJobsMap = new HashMap<>(); 

    @Autowired 
    JobRepository jobRepository; 

    @Autowired 
    MyFirstJob myFirstJob; 

    @Autowired 
    MySecondJob mySecondJob; 

    @Autowired 
    TaskScheduler scheduler; 

    @PostConstruct 
    public void initScheduler() { 
     schduledJobsMap.put(MyFirstJob.JOB, myFirstJob); 
     schduledJobsMap.put(MySecondJob.JOB, mySecondJob); 

     startAll(); 
    } 

    public void restart(String job) { 
     stop(job); 
     start(job); 
    } 

    public void stop(String job) { 
     schduledJobsMap.get(job).stop(); 
    } 

    public void start(String job) { 
     schduledJobsMap.get(job).start(); 
    } 

    public void startAll() { 
     for (SchedulerObjectInterface schedulerObjectInterface : schduledJobsMap.values()) { 
      schedulerObjectInterface.start(); 
     } 
    } 

    @Bean 
    public TaskScheduler scheduler() { 
     return new ThreadPoolTaskScheduler(); 
    } 
} 
0

考虑使用此方法。除了添加和删除计划任务之外,您可以每隔一分钟(或另一个精确度)检查视图的实际时间,并立即运行必要的任务。这会更容易。检查Quartz Scheduler,它的CronExpression有isSatisfiedBy(日期日期)方法。

@Scheduled(cron = "5 * * * * *) // do not set seconds to zero, cause it may fit xx:yy:59 
public void runTasks() { 
    LocalTime now = LocalTime.now(); // or Date now = new Date(); 
    // check and run 
}