2016-08-25 4 views
3

Ich habe eine Spring-Boot-Anwendung, die eine Orchestration-Service für mehrere andere Prozesse, die wir auslösen möchten, wird. Ich habe es derzeit eingerichtet mit Spring Scheduling ziehen Cron dynamisch aus einer Datenbank. Ich warf eine Rest-Methode ein, um den Prozess auszulösen, um neue Cron-Informationen aus der Datenbank zu ziehen. Diese Logik funktioniert alle korrekt. Das einzige "Problem" ist, dass es die neuen Cron-Informationen erst beim nächsten geplanten Lauf verwendet, der zur eigentlichen Frage kommt. Gibt es eine Möglichkeit, den aktuellen Trigger zu unterbrechen und einen erneut mit den aktualisierten Cron-Informationen zu planen. Hier ist die Anwendung als Referenz:Interrupt Feder Scheduler Aufgabe vor dem nächsten Aufruf

package com.bts.poc; 

import org.apache.log4j.Logger; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.scheduling.Trigger; 
import org.springframework.scheduling.TriggerContext; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.scheduling.annotation.SchedulingConfigurer; 
import org.springframework.scheduling.config.ScheduledTaskRegistrar; 
import org.springframework.scheduling.support.CronTrigger; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

import java.util.Date; 

@SpringBootApplication 
@EnableScheduling 
@RestController 
@RequestMapping("/APSCommon/Scheduling") 
public class Application implements SchedulingConfigurer { 

    @Autowired 
    private DynamicCron dynamicCron; 
    @Autowired 
    PropertyManager propertyManager; 

    public static void main(String[] args) throws Exception { 
     SpringApplication.run(Application.class); 
    } 

    private String cronConfig() { 
     String cronTabExpression = propertyManager.getProperty("COMPANY", "JOB_NAME","CRON_EXPRESSION"); 
     return cronTabExpression; 
    } 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 
     taskRegistrar.addTriggerTask(new Runnable() { 
      @Override 
      public void run() { 
       dynamicCron.runJob(); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       String cron = cronConfig(); 
       CronTrigger trigger = new CronTrigger(cron); 
       Date nextExec = trigger.nextExecutionTime(triggerContext); 
       DynamicCron.cronExpression = cron; 
       return nextExec; 
      } 
     }); 
    } 

    @RequestMapping(value = "/reloadScheduling", method = RequestMethod.GET) 
    public String reloadScheduling() { 
     PropertyManager.setResetProperties(true); 
     return "schedules will be altered next run"; 
    } 
} 
+0

Löst das dein Problem? http://StackOverflow.com/a/13869342/6737860 –

+0

Es gibt keinen Weg, den ich gefunden habe, wo ich das ScheduledFuture bekommen kann, wenn ich den ScheduledTaskRegistrar plane. Ich werde es ein wenig genauer betrachten und aktualisieren. –

Antwort

4

So SchedulingConfigurer- mit> configureTasks Sie keinen Zugriff auf die ScheduledFuture (en) im Frühjahr Version bekommen kann ich (4.2.7.RELEASE) verwende. Von mehreren Posts, die ich gelesen habe, wurde es als mögliche Funktionalität für die Zukunft erwähnt. Ich habe um diesen durch folgende Maßnahmen:

package com.bts.poc; 

import com.bts.poc.service.DynamicCron; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.context.web.SpringBootServletInitializer; 
import org.springframework.context.annotation.Bean; 
import org.springframework.scheduling.TaskScheduler; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 
import org.springframework.scheduling.support.CronTrigger; 
import org.springframework.web.bind.annotation.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.TimeZone; 
import java.util.concurrent.ScheduledFuture; 

@SpringBootApplication(exclude = MessageSourceAutoConfiguration.class) 
@EnableScheduling 
@RestController 
public class Application extends SpringBootServletInitializer { 

    @Autowired 
    private DynamicCron dynamicCron; 
    @Autowired 
    private PropertyManager propertyManager; 
    private static List<ScheduledFuture> scheduledFutures = new ArrayList<>(); 
    private static final Logger LOGGER = LoggerFactory.getLogger(Application.class); 
    private static TaskScheduler scheduler; 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(Application.class); 
    } 

    private String cronConfig() { 
     return propertyManager.getProperty("COMPANY", "JOB_NAME", "CRON_EXPRESSION"); 
    } 

    @RequestMapping(value = {"scheduling/start"}, method = RequestMethod.GET) 
    public @ResponseBody String startScheduling() { 
     scheduleAll(); 

     LOGGER.info("Scheduling of jobs has been started."); 
     return "Scheduling of jobs has been started."; 
    } 

    @RequestMapping(value = {"scheduling/cancel"}, method = RequestMethod.GET) 
    public @ResponseBody String cancelScheduling() { 
     cancelAll(); 

     LOGGER.info("Cancelling all scheduled jobs."); 
     return "Cancelling all scheduled jobs."; 
    } 

    private void scheduleAll() { 
     LOGGER.info("Scheduling all applications to run."); 
     cancelAll(); 

     //eventually go through the database and load all jobs to be scheduled here. 
     schedule(cronConfig()); 
    } 

    /** 
    * Cancel all the scheduled reports 
    */ 
    private void cancelAll() { 
     for (ScheduledFuture scheduledFuture : scheduledFutures) { 
      scheduledFuture.cancel(true); 
     } 
     scheduledFutures.clear(); 
    } 

    /** 
    * Schedule the scheduled report with the given cron schedule information 
    */ 
    private void schedule(String cronSchedule) { 
     TimeZone tz = TimeZone.getDefault(); 
     LOGGER.info("Setting up application {} to execute with cron string: '{}'.", cronSchedule); 
     CronTrigger trigger = new CronTrigger(cronSchedule, tz); 

     scheduler = scheduler(); 
     if (scheduler == null) { 
      LOGGER.error("Unable to schedule job as scheduler was not found"); 
      return; 
     } 

     ScheduledFuture<?> future = scheduler.schedule(new DynamicCron(), trigger); 
     scheduledFutures.add(future); 
    } 

    @Bean 
    public TaskScheduler scheduler() { 
     if (scheduler == null) { 
      ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); 
      scheduler.setPoolSize(10); 
      scheduler.afterPropertiesSet(); 
     } 
     return scheduler; 
    } 
} 

Diese im Grunde die Funktionalität repliziert die ScheduledTaskRegistrar bietet mit dem Sie den ScheduledFuture (s) zu verwalten. Hoffentlich kann dies jemand anderem in der Zukunft helfen.

Verwandte Themen