Jak sparametryzować @Scheduled (fixedDelay) za pomocą języka wyrażeń Spring 3.0?

125

Korzystając z możliwości Spring 3.0 do adnotacji zaplanowanego zadania, chciałbym ustawić fixedDelayparametr as z mojego pliku konfiguracyjnego, zamiast podłączać go na stałe do mojej klasy zadań, tak jak obecnie ...

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

Niestety wygląda na to, że za pomocą języka Spring Expression Language (SpEL) @Valuezwraca obiekt typu String, który z kolei nie może być automatycznie dopasowany do długiej wartości wymaganej przez fixedDelayparametr.

ngeek
źródło

Odpowiedzi:

26

Myślę, że @Scheduledadnotacja nie wchodzi w grę. Więc może rozwiązaniem dla Ciebie byłoby użycie task-scheduledkonfiguracji XML. Rozważmy ten przykład (skopiowany z dokumentu Spring ):

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

... lub jeśli rzut ze String na Long nie zadziałał, coś takiego:

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

Ponownie, nie próbowałem żadnej z tych konfiguracji, ale mam nadzieję, że może ci to trochę pomóc.

Grzegorz Oledzki
źródło
Dzięki, konfiguracja XML załatwiła sprawę. Jestem trochę zaskoczony, że adnotacja wydaje się być tak związana z wartościami ciągów, w każdym razie idę starą szkołą ;-)
ngeek
1
Czy istnieje odpowiednik Java dla powyższej konfiguracji?
amique
@Grzegorz Oledzki jaka będzie wartość parametru „someObject” w tagu <task: schedule>. Jeśli kontroler ma więcej niż jedną metodę, która wymaga stałego opóźnienia i opóźnienia początkowego, jak zostanie to rozwiązane?
Mohit Singh
422

Spring v3.2.2 dodał parametry String do oryginalnych 3 długich parametrów, aby to obsłużyć. fixedDelayString, fixedRateStringiinitialDelayString są teraz również dostępne.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
źródło
3
@Avi Ta odpowiedź pojawiła się trzy lata po pytaniu PO. W momencie zadawania pytania (i zaakceptowanej odpowiedzi) ta funkcja nie istniała.
medveshonok117
@ medveshonok117 Rozumiem. Dzięki
Avi
51

Możesz użyć @Scheduledadnotacji, ale tylko razem z cronparametrem:

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

Twój 5-sekundowy interwał można wyrazić jako "*/5 * * * * *". Jednak, jak rozumiem, nie można zapewnić precyzji poniżej 1 sekundy.

kan
źródło
9
Wyrażenie cron, które pokazałeś, jest odpowiednikiem fixedRate, które różni się od fixedDelay
codebox
4

W Spring Boot 2 możemy użyć języka Spring Expression Language (SpPL) dla @Scheduledwłaściwości adnotacji:

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

application.propertiesPlik będzie wyglądać następująco:

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

Otóż ​​to. Oto artykuł, który szczegółowo wyjaśnia planowanie zadań.

attacomsian
źródło
1

Myślę, że możesz sam przeliczyć wartość, definiując fasolę. Nie próbowałem tego , ale myślę, że podejście podobne do następującego może być dla Ciebie przydatne:

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

gdzie:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
źródło
Dzięki, to brzmi jak w jedną stronę, ale szczerze mówiąc liczyłem na bardziej eleganckie ("sprężyste") rozwiązanie :-)
ngeek
2
Niestety to nie zadziała, ponieważ atrybut adnotacji @Scheduled fixedDelay wymaga przypisania (długiej) stałej.
ngeek
Ach, zgadza się. Więc myślę, że nie możesz tego zrobić z @Scheduledadnotacją.
Grzegorz Oledzki