Como parametrizar @Scheduled (fixedDelay) com a linguagem de expressão do Spring 3.0?

125

Ao usar o recurso Spring 3.0 para anotar uma tarefa agendada, eu gostaria de definir o fixedDelayparâmetro as do meu arquivo de configuração, em vez de conectá-lo à minha classe de tarefa, como atualmente ...

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

Infelizmente, parece que com os meios da Spring Expression Language (SpEL) @Valueretorna um objeto String que, por sua vez, não pode ser encaixotado automaticamente em um valor longo, conforme exigido pelo fixedDelayparâmetro.

ngeek
fonte

Respostas:

26

Eu acho que a @Scheduledanotação está fora de questão. Então, talvez uma solução para você seria usar a task-scheduledconfiguração XML. Vamos considerar este exemplo (copiado do documento do Spring ):

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

... ou se o elenco de String para Long não funcionasse, algo assim:

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

Novamente, eu não tentei nenhuma dessas configurações, mas espero que possa ajudá-lo um pouco.

Grzegorz Oledzki
fonte
Obrigado, a configuração XML fez o truque. Estou pouco surpreso que a anotação parece tão ligado a valores de cadeia, de qualquer maneira, eu vou com a maneira old-school ;-)
ngeek
1
Existe algum equivalente em Java para a configuração acima?
22614 amique
@Grzegorz Oledzki qual será o valor de "someObject" na tag <task: schedule>. Se um controlador tiver mais de um método que precise de atraso fixo e atraso inicial, como isso será tratado?
Mohit Singh
422

O Spring v3.2.2 adicionou parâmetros de String aos 3 parâmetros longos originais para lidar com isso. fixedDelayString, fixedRateStringe initialDelayStringagora também estão disponíveis.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
fonte
3
@Avi Esta resposta vem três anos após a pergunta do OP. No momento da pergunta (e resposta aceita), esse recurso não existia.
medveshonok117
@ medveshonok117 Entendi. Obrigado
Avi
51

Você pode usar a @Scheduledanotação, mas cronapenas com o parâmetro:

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

Seu intervalo de 5 segundos pode ser expresso como "*/5 * * * * *". No entanto, pelo que entendi, você não pode fornecer menos de 1 segundo de precisão.

kan
fonte
9
A expressão cron que você mostrou é equivalente a fixedRate, que é diferente de fixedDelay
codebox
4

No Spring Boot 2, podemos usar o Spring Expression Language (SpPL) para @Scheduledpropriedades de anotação:

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

O application.propertiesarquivo ficará assim:

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

É isso aí. Aqui está um artigo que explica o agendamento de tarefas em detalhes.

attacomsian
fonte
1

Eu acho que você pode converter o valor você mesmo definindo um bean. Eu não tentei isso , mas acho que uma abordagem semelhante à seguinte pode ser útil para você:

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

Onde:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
fonte
Obrigado, isso soa como uma maneira, mas para ser honesto eu estava esperando por uma solução ( "springish") mais elegante :-)
ngeek
2
Infelizmente, isso não funcionará, pois o atributo de anotação @Scheduled fixedDelay exige que uma constante (longa) seja atribuída.
N
Ah, está certo. Então eu acho que você não pode fazer isso com a @Scheduledanotação então.
Grzegorz Oledzki