Wie parametriere ich @Scheduled (fixedDelay) mit der Ausdruckssprache Spring 3.0?

125

Wenn Sie die Spring 3.0-Funktion zum Kommentieren einer geplanten Aufgabe verwenden, möchte ich den fixedDelayParameter as aus meiner Konfigurationsdatei festlegen , anstatt ihn wie derzeit fest mit meiner Aufgabenklasse zu verbinden ...

@Scheduled(fixedDelay = 5000)
public void readLog() {
        ...
}

Leider scheint es, dass mit den Mitteln der Spring Expression Language (SpEL) @Valueein String-Objekt zurückgegeben wird, das wiederum nicht automatisch auf einen langen Wert geboxt werden kann, wie es der fixedDelayParameter erfordert .

ngeek
quelle

Antworten:

26

Ich denke, die @ScheduledAnmerkung kommt nicht in Frage. Eine Lösung für Sie wäre möglicherweise die Verwendung der task-scheduledXML-Konfiguration. Betrachten wir dieses Beispiel (kopiert aus Spring doc ):

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog" 
               fixed-rate="#{YourConfigurationBean.stringValue}"/>
</task:scheduled-tasks>

... oder wenn die Besetzung von String zu Long nicht funktioniert hätte, würde so etwas:

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="someObject" method="readLog"
            fixed-rate="#{T(java.lang.Long).valueOf(YourConfigurationBean.stringValue)}"/>
</task:scheduled-tasks>

Auch hier habe ich keines dieser Setups ausprobiert, aber ich hoffe, es könnte Ihnen ein bisschen helfen.

Grzegorz Oledzki
quelle
Danke, die XML-Konfiguration hat es geschafft. Ich bin ein bisschen überrascht, dass die Annotation sowieso so stark an String-Werte gebunden zu sein scheint, dass ich mich an die alte Schule
halte ;-)
1
Gibt es ein Java-Äquivalent für die obige Konfiguration?
Amique
@Grzegorz Oledzki Was ist der Wert von "someObject" unter dem Tag <task: Scheduled>? Wenn ein Controller mehr als eine Methode hat, die eine feste Verzögerung und eine anfängliche Verzögerung benötigt, wie wird das dann gehandhabt?
Mohit Singh
422

Spring v3.2.2 hat String-Parameter zu den ursprünglichen 3 langen Parametern hinzugefügt, um dies zu handhaben. fixedDelayString, fixedRateStringUnd initialDelayStringist jetzt auch verfügbar.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
quelle
3
@Avi Diese Antwort kommt drei Jahre nach der Frage des OP. Zum Zeitpunkt der Frage (und der akzeptierten Antwort) war diese Funktion nicht vorhanden.
Medveshonok117
@ medveshonok117 Verstanden. Vielen Dank
Avi
51

Sie können die @ScheduledAnmerkung verwenden, jedoch nur zusammen mit dem cronParameter:

@Scheduled(cron = "${yourConfiguration.cronExpression}")

Ihr 5-Sekunden-Intervall könnte ausgedrückt werden als "*/5 * * * * *". Soweit ich weiß, können Sie jedoch nicht weniger als 1 Sekunde genau angeben.

kan
quelle
9
Der Cron-Ausdruck, den Sie gezeigt haben, entspricht fixedRate, was sich von fixedDelay
Codebox
4

In Spring Boot 2 können wir Spring Expression Language (SpPL) für @ScheduledAnnotationseigenschaften verwenden:

@Scheduled(fixedRateString = "${fixed-rate.in.milliseconds}")
public void fixedRate() {
    // do something here
}

@Scheduled(fixedDelayString = "${fixed-delay.in.milliseconds}")
public void fixedDelay() {
    // do something here
}

@Scheduled(cron = "${cron.expression}")
public void cronExpression() {
    // do something here
}

Die application.propertiesDatei sieht folgendermaßen aus:

fixed-rate.in.milliseconds=5000
fixed-delay.in.milliseconds=4000
cron.expression=0 15 5 * * FRI

Das ist es. In diesem Artikel wird die Aufgabenplanung ausführlich erläutert.

Attacomsian
quelle
1

Ich denke, Sie können den Wert selbst konvertieren, indem Sie eine Bean definieren. Ich habe das noch nicht ausprobiert , aber ich denke, der folgende Ansatz könnte für Sie nützlich sein:

<bean id="FixedDelayLongValue" class="java.lang.Long"
      factory-method="valueOf">
    <constructor-arg value="#{YourConfigurationBean.stringValue}"/>
</bean>

wo:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
quelle
Danke, das klingt nach einer Möglichkeit, aber um ehrlich zu sein, habe ich auf eine elegantere ("federnde") Lösung
gehofft
2
Leider funktioniert dies nicht, da für das @ Scheduled-Annotation-Attribut fixedDelay eine (lange) Konstante zugewiesen werden muss.
Ngeek
Ah, das stimmt. Ich denke, Sie können es dann nicht mit der @ScheduledAnmerkung machen.
Grzegorz Oledzki