2015-05-20 4 views
17

Ist es möglich Spring Service-Methode nur einmal zu genau festgelegten Zeitpunkt zu planen? Zum Beispiel ist die aktuelle Zeit 14 Uhr, aber wenn ich den Aktions-Button drücke, möchte ich, dass meine Service-Methode um 20 Uhr beginnt. Ich bin vertraut mit @ Scheduled Annotation und ich bin mir nicht sicher, wie Cron-Ausdruck nicht in regelmäßigen Abständen ausgeführt werden soll. Dieser wird jeden Tag um 20 Uhr angezündet @Scheduled(cron = "0 0 20 * * ?").
Irgendwelche Vorschläge?Spring Scheduling Task - nur einmal ausführen

+0

Sie können Quartz Scheduler verwenden :) –

Antwort

16

Sie können eine der Implementierungen von TaskScheduler von Spring verwenden. Ich habe unten ein Beispiel mit einem angegeben, das nicht zu viel Konfiguration erfordert (ConcurrentTaskScheduler, der einen geplanten Executor mit einem einzigen Thread umschließt).

Die einfachste Methode ist die eine Zeitplan benannt, die nur eine Runnable und Datum stattfindet. Das führt dazu, dass die Task einmal nach der angegebenen Zeit ausgeführt wird. Alle anderen Methoden können Tasks so planen, dass sie wiederholt ausgeführt werden.

Lesen Sie mehr über task execution & scheduling

Einfache Arbeitsbeispiel:

private TaskScheduler scheduler; 

Runnable exampleRunnable = new Runnable(){ 
    @Override 
    public void run() { 
     System.out.println("Works"); 
    } 
}; 

@Async 
public void executeTaskT() { 
    ScheduledExecutorService localExecutor = Executors.newSingleThreadScheduledExecutor(); 
    scheduler = new ConcurrentTaskScheduler(localExecutor); 

    scheduler.schedule(exampleRunnable, 
      new Date(1432152000000L));//today at 8 pm UTC - replace it with any timestamp in miliseconds to text 
} 

... 

executeTaskT() //call it somewhere after the spring application has been configured 

Hinweis:

Unterstützung aktivieren für @Scheduled und @Async Anmerkungen hinzufügen @EnableScheduling und @EnableAsync zu einer Ihrer @Configuration Klassen


aktualisiert - die geplante Aufgabe Cancelling

Taskscheduler Zeitplan Methode eine ScheduledFuture kehrt das ist eine verzögert Ergebnis tragende Aktion, die abgebrochen werden kann.

Um es abzubrechen, müssen Sie also ein Handle für die geplante Aufgabe behalten (d. H. Das ScheduledFuture return-Objekt behalten).

Änderungen an dem Code oben für die Aufgabe Cancelling:

  1. Deklarieren Sie die ScheduledFuture außerhalb Ihres executeTaskT Methode. private ScheduledFuture scheduledFuture;

  2. ändern Sie bitte Ihren Anruf die Rückkehr Objekt als solches zu halten zu planen: scheduledFuture = scheduler.schedule(exampleRunnable, new Date(1432152000000L));

  3. Anruf auf dem scheduledFuture Objekt irgendwo im Code Abbrechen boolean mayInterruptIfRunning = true; scheduledFuture.cancel(mayInterruptIfRunning);

+0

Dies funktioniert. Ich erweiterte ConcurrentTaskScheduler Instanziierung mit Server-Thread-Management-Task-Executor wie diese 'scheduler = new ConcurrentTaskScheduler (workManagerTaskExecutor, Executors.newSingleThreadScheduledExecutor()) '. Es ist eine Art von 'org.springframework.scheduling.commonj.WorkManagerTaskExecutor' und wird vom Server-JNDI-Register bereitgestellt. – shx

+1

Großartig, hat für mich gearbeitet. btw, wenn mit Parametern runnable benötigt wird, können Sie eine Methode schreiben, die Parameter akzeptiert und Runnable zurückgibt und diese Methode dann im Scheduler mit Parameter scheduler.schedule (createRunnable (param1), new Date (1432152000000L)) übergibt; –

+1

Ist @Async obligatorisch, um es zu erreichen? – Angom

0

Um nicht create ScheduledExecutorService und ConcurrentTaskScheduler bei jedem Methodenaufruf ist es bequem, TaskScheduler bei der Erstellung von Diensten zu initialisieren, z

private final TaskScheduler taskScheduler = 
       new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(10)); 

@Async hat keinen Sinn, da wir nur Aufgabe und Verlassen Methode planen.