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

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

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

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

Ответ 1

Я думаю, аннотация @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 to Long не работает, что-то вроде этого:

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

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

Ответ 2

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

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}

Ответ 3

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

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

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

Ответ 4

Я думаю, вы можете преобразовать значение самостоятельно, указав 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>

Ответ 5

В 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

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