Comment paramétrer @Scheduled (fixedDelay) avec le langage d'expression Spring 3.0?

125

Lorsque vous utilisez la fonctionnalité Spring 3.0 pour annoter une tâche planifiée, je voudrais définir le fixedDelayparamètre as de mon fichier de configuration, au lieu de le câbler en dur dans ma classe de tâches, comme actuellement ...

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

Malheureusement, il semble qu'avec les moyens du Spring Expression Language (SpEL) @Valuerenvoie un objet String qui à son tour ne peut pas être automatiquement encadré à une valeur longue comme l'exige le fixedDelayparamètre.

ngeek
la source

Réponses:

26

Je suppose que l' @Scheduledannotation est hors de question. Alors peut-être qu'une solution pour vous serait d'utiliser la task-scheduledconfiguration XML. Prenons cet exemple (copié de Spring doc ):

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

... ou si la conversion de String en Long ne fonctionnait pas, quelque chose comme ceci:

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

Encore une fois, je n'ai essayé aucune de ces configurations, mais j'espère que cela pourra vous aider un peu.

Grzegorz Oledzki
la source
Merci, la configuration XML a fait l'affaire. Je suis un peu surpris que l'annotation semble si liée aux valeurs de chaîne, de toute façon, je vais à l'ancienne ;-)
ngeek
1
Existe-t-il un équivalent Java pour la configuration ci-dessus?
amique
@Grzegorz Oledzki quelle sera la valeur de "someObject" sous la balise <tâche: planifiée>. Si un contrôleur a plus d'une méthode qui nécessite un délai fixe et un délai initial, comment cela sera-t-il géré?
Mohit Singh
422

Spring v3.2.2 a ajouté des paramètres String aux 3 paramètres longs d'origine pour gérer cela. fixedDelayString, fixedRateStringet initialDelayStringsont maintenant disponibles aussi.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
la source
3
@Avi Cette réponse intervient trois ans après la question du PO. Au moment de la question (et de la réponse acceptée), cette fonctionnalité n'existait pas.
medveshonok117
@ medveshonok117 J'ai compris. Merci
Avi
51

Vous pouvez utiliser l' @Scheduledannotation, mais avec le cronparamètre uniquement:

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

Votre intervalle de 5 secondes peut être exprimé par "*/5 * * * * *". Cependant, si je comprends bien, vous ne pouvez pas fournir une précision inférieure à 1 seconde.

Kan
la source
9
L'expression cron que vous avez affichée est équivalente à fixedRate, qui est différent de fixedDelay
codebox
4

Dans Spring Boot 2, nous pouvons utiliser Spring Expression Language (SpPL) pour les @Scheduledpropriétés d'annotation:

@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
}

Le application.propertiesfichier ressemblera à ceci:

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

C'est tout. Voici un article qui explique en détail la planification des tâches.

attacomsien
la source
1

Je suppose que vous pouvez convertir la valeur vous-même en définissant un bean. Je n'ai pas essayé cela , mais je suppose qu'une approche similaire à la suivante pourrait vous être utile:

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

où:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
la source
Merci, cela semble être une solution, mais pour être honnête, j'espérais une solution plus élégante ("printanière") :-)
ngeek
2
Malheureusement, cela ne fonctionnera pas, car l'attribut d'annotation @Scheduled fixedDelay nécessite l'attribution d'une (longue) constante.
ngeek
Ah, c'est vrai. Donc je suppose que vous ne pouvez pas le faire avec l' @Scheduledannotation alors.
Grzegorz Oledzki