Как параметризовать @Scheduled (fixedDelay) с помощью языка выражений Spring 3.0?

126

При использовании возможности Spring 3.0 для аннотирования запланированной задачи я хотел бы установить fixedDelay параметр as из моего файла конфигурации, вместо того, чтобы жестко связывать его с моим классом задачи, как в настоящее время ...

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

К сожалению, кажется, что средства Spring Expression Language (SpEL) @Valueвозвращают объект String, который, в свою очередь, не может быть автоматически упакован в длинное значение, как того требует fixedDelayпараметр.

ngeek
источник

Ответы:

26

Думаю, об @Scheduledаннотации не может быть и речи. Так что, возможно, решением для вас будет использование task-scheduledконфигурации XML. Рассмотрим этот пример (скопирован из Spring doc ):

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

... или если приведение из String в Long не сработало, что-то вроде этого:

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

Опять же, я не пробовал ни одну из этих настроек, но надеюсь, что это может вам немного помочь.

Гжегож Оледски
источник
Спасибо, конфигурация XML сделала свое дело. Я немного удивлен, что аннотация кажется такой привязанной к строковым значениям, в любом случае, я
придерживаюсь
1
Есть ли эквивалент Java для вышеуказанной конфигурации?
amique
@Grzegorz Oledzki, каким будет значение someObject в теге <task :duled>. Если у контроллера есть более одного метода, для которого требуется фиксированная задержка и начальная задержка, то как это будет обрабатываться?
Мохит Сингх
423

Spring v3.2.2 добавил параметры String к исходным 3 длинным параметрам, чтобы справиться с этим. fixedDelayString, fixedRateStringи initialDelayStringтеперь тоже доступны.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
источник
3
@Avi Этот ответ приходит через три года после вопроса ОП. На момент вопроса (и принятого ответа) этой функции не существовало.
medveshonok117
@ medveshonok117 Понятно. Спасибо
Avi
51

Вы можете использовать @Scheduledаннотацию, но только вместе с cronпараметром:

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

Ваш 5-секундный интервал можно выразить как "*/5 * * * * *". Однако, насколько я понимаю, вы не можете обеспечить точность менее 1 секунды.

кан
источник
9
Выражение cron, которое вы показали, эквивалентно fixedRate, которое отличается от fixedDelay
codebox
4

В Spring Boot 2 мы можем использовать Spring Expression Language (SpPL) для @Scheduledсвойств аннотации:

@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.propertiesФайл будет выглядеть следующим образом :

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

Вот и все. Вот статья , в которой подробно объясняется планирование задач.

attacomsian
источник
1

Я думаю, вы можете преобразовать значение самостоятельно, определив bean. Я этого не пробовал , но полагаю, что вам может быть полезен подход, подобный следующему:

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

где:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Гжегож Оледски
источник
Спасибо, это звучит так, но, честно говоря, я надеялся на более элегантное («пружинящее») решение :-)
ngeek
2
К сожалению, это не сработает, поскольку для атрибута @Scheduled аннотации fixedDelay требуется назначить (длинную) константу.
ngeek 08
Ах, верно. Думаю, тогда с @Scheduledаннотацией этого не сделать .
Grzegorz Oledzki 08