Planification d’un travail avec Spring par programmation (avec fixedRate défini dynamicment)

Actuellement j’ai ceci:

@Scheduled(fixedRate=5000) public void getSchedule(){ System.out.println("in scheduled job"); } 

Je pourrais changer cela pour utiliser une référence à une propriété

 @Scheduled(fixedRate=${myRate}) public void getSchedule(){ System.out.println("in scheduled job"); } 

Cependant, je dois utiliser une valeur obtenue par programmation afin de pouvoir modifier la planification sans redéployer l’application. Quel est le meilleur moyen? Je me rends compte que l’utilisation des annotations peut ne pas être possible …

En utilisant un Trigger vous pouvez calculer la prochaine exécution à la volée.

Quelque chose comme ça devrait faire l’affaire (adapté de Javadoc pour @EnableScheduling ):

 @Configuration @EnableScheduling public class MyAppConfig implements SchedulingConfigurer { @Autowired Environment env; @Bean public MyBean myBean() { return new MyBean(); } @Bean(destroyMethod = "shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); taskRegistrar.addTriggerTask( new Runnable() { @Override public void run() { myBean().getSchedule(); } }, new Trigger() { @Override public Date nextExecutionTime(TriggerContext sortingggerContext) { Calendar nextExecutionTime = new GregorianCalendar(); Date lastActualExecutionTime = sortingggerContext.lastActualExecutionTime(); nextExecutionTime.setTime(lastActualExecutionTime != null ? lastActualExecutionTime : new Date()); nextExecutionTime.add(Calendar.MILLISECOND, env.getProperty("myRate", Integer.class)); //you can get the value from wherever you want return nextExecutionTime.getTime(); } } ); } } 

Vous pouvez également utiliser cette approche simple:

 private int refreshTickNumber = 10; private int tickNumber = 0; @Scheduled(fixedDelaySsortingng = "${some.rate}") public void nextStep() { if (tickNumber < refreshTickNumber) { tickNumber++; return; } else { tickNumber = 0; } // some code } 

refreshTickNumber est entièrement configurable à l'exécution et peut être utilisé avec les annotations @Value .

vous pouvez gérer le redémarrage de la planification en utilisant TaskScheduler et ScheduledFuture:

 @Configuration @EnableScheduling @Component public class CronConfig implements SchedulingConfigurer , SchedulerObjectInterface{ @Autowired private ScheduledFuture future; @Autowired private TaskScheduler scheduler; @Bean public SchedulerController schedulerBean() { return new SchedulerController(); } @Bean(destroyMethod = "shutdown") public Executor taskExecutor() { return Executors.newScheduledThreadPool(100); } @Override public void start() { future = scheduler.schedule(new Runnable() { @Override public void run() { //System.out.println(JOB + " Hello World! " + new Date()); schedulerBean().schedulerJob(); } }, new Trigger() { @Override public Date nextExecutionTime(TriggerContext sortingggerContext) { Calendar nextExecutionTime = new GregorianCalendar(); Date lastActualExecutionTime = sortingggerContext.lastActualExecutionTime(); nextExecutionTime.setTime(convertExpresssiontoDate());//you can get the value from wherever you want return nextExecutionTime.getTime(); } }); } @Override public void stop() { future.cancel(true); } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { // TODO Auto-generated method stub start(); } } 

interface pour start stop:

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

maintenant vous pouvez arrêter et recommencer (redémarrer) Planification en utilisant @Autowired SchedulerObjectInterface