2013-03-06 11 views
19

Ich habe die Anforderung, einen Batch-Job in einem festen Intervall auszuführen und die Zeit dieses Batch-Jobs zur Laufzeit ändern zu können. Dazu stieß ich auf @Scheduled Annotation, die im Rahmen von Spring zur Verfügung gestellt wurde. Aber ich bin mir nicht sicher, wie ich den Wert von fixedDelay zur Laufzeit ändern würde. Ich habe etwas gegoogelt, aber nichts Nützliches gefunden.So ändern Sie Spring's @Scheduled fixedDelay zur Laufzeit

+0

Ich sehe Sie die beste Antwort akzeptiert, aber ich sehe immer noch, es gab einige ungelöste Probleme. Wurde das NPE-Problem behoben? Ist es möglich, dass Sie die gesamte Lösung dafür bereitstellen?Prost – despot

+0

Mögliche Duplikate von [Einen Job mit Spring programmgesteuert einplanen (wobei fixedRate dynamisch gesetzt wird)] (http://stackoverflow.com/questions/14630539/slaming-a-job-with-spring-programmatical-with-fixedrate-set- dynamisch) –

Antwort

17

Sie können eine Trigger verwenden, um die nächste Ausführungszeit dynamisch festzulegen. Siehe meine Antwort hier:

Scheduling a job with Spring programmatically (with fixedRate set dynamically)

+0

Genau das, was ich gesucht habe - Danke Kumpel – jsf

+0

FYI - Hinterließ einen Kommentar zu 'NullPointerException' Bug im Code bemerkt. – jsf

+0

Gibt es eine Möglichkeit, den aktuellen Trigger zu unterbrechen und seinen Wert zu ändern, während er schläft. – jsf

2

AFAIK die Spring API lässt Sie nicht auf die Interna zugreifen, die Sie brauchen, um den Trigger zu ändern. Aber Sie könnten stattdessen manuell konfigurieren, um die Bohnen:

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> 
    <property name="jobDetail" ref="jobDetail" /> 
    <property name="startDelay" value="10000" /> 
    <property name="repeatInterval" value="50000" /> 
</bean> 

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
    <property name="triggers"> 
     <list> 
      <ref bean="simpleTrigger" /> 
     </list> 
    </property> 
</bean> 

Dann dokumentiert wie in SchedulerFactoryBean:

Für die dynamische Registrierung von Arbeitsplätzen zur Laufzeit, diese SchedulerFactoryBean eine Bohne Bezug auf verwendet die direkten Zugriff auf die bekommen Quartz Scheduler (org.quartz.Scheduler). Auf diese Weise können Sie neue Jobs und Trigger erstellen sowie den gesamten Scheduler steuern und überwachen.

33

Im Frühjahr Boot, direkt eine Anwendung Eigenschaft nutzen kann!

Zum Beispiel:

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000") 
private void process() { 
    // your impl here 
} 

Beachten Sie, dass Sie auch einen Standardwert haben, falls können die Eigenschaft nicht definiert ist, zB einen Standardwert von „60“ haben (Sekunden):

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000") 

Andere Dinge, die ich entdeckt:

  • das Verfahren nichtig muss
  • die Methode keine Parameter
  • das Verfahren haben müssen möglicherweise private

sein Ich fand private Sichtbarkeit praktisch bedienen zu können, und verwendet es auf diese Weise:

@Service 
public class MyService { 
    public void process() { 
     // do something 
    } 

    @Scheduled(fixedDelayString = "${my.poll.fixed.delay.seconds}000") 
    private void autoProcess() { 
     process(); 
    } 
} 

Being private kann die geplante Methode lokal für Ihren Dienst sein und nicht Teil der API Ihres Dienstes werden.

Auch dieser Ansatz ermöglicht es der process()-Methode, einen Wert zurückzugeben, der eine @Scheduled-Methode möglicherweise nicht. Zum Beispiel können Sie Ihre process() Methode wie folgt aussehen:

public ProcessResult process() { 
    // do something and collect information about what was done 
    return processResult; 
} 

einige Informationen darüber zu geben, was bei der Verarbeitung geschah.

+0

Danke, 'fixedDelayString' ist das, was ich gesucht habe – prettyvoid

+0

Große Antwort. Funktioniert wie beschrieben. – flash

+1

@Bohemain Danke für die Lösung, aber wie wird das FixedDelay zur Laufzeit aktualisiert? –

Verwandte Themen