¿Cómo parametrizar @Scheduled (fixedDelay) con el lenguaje de expresión Spring 3.0?

125

Al usar la capacidad de Spring 3.0 para anotar una tarea programada, me gustaría establecer el fixedDelayparámetro como desde mi archivo de configuración, en lugar de conectarlo a mi clase de tarea, como actualmente ...

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

Desafortunadamente, parece que con los medios del lenguaje de expresión de primavera (SpEL) se @Valuedevuelve un objeto String que, a su vez, no se puede encuadrar automáticamente en un valor largo como lo requiere el fixedDelayparámetro.

ngeek
fuente

Respuestas:

26

Supongo que la @Scheduledanotación está fuera de discusión. Entonces, tal vez una solución para usted sería usar la task-scheduledconfiguración XML. Consideremos este ejemplo (copiado de Spring doc ):

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

... o si el elenco de String a Long no funcionara, algo como esto:

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

Nuevamente, no he probado ninguna de estas configuraciones, pero espero que pueda ayudarlo un poco.

Grzegorz Oledzki
fuente
Gracias, la configuración XML hizo el truco. Estoy un poco sorprendido de que la anotación parezca tan ligada a los valores de cadena, de todos modos, sigo la vieja escuela ;-)
ngeek
1
¿Hay algún equivalente de Java para la configuración anterior?
amique
@Grzegorz Oledzki, ¿cuál será el valor de "someObject" en la etiqueta <tarea: programada>? Si un controlador tiene más de un método que necesita un retraso fijo y un retraso inicial, ¿cómo se manejará?
Mohit Singh el
422

Spring v3.2.2 ha agregado parámetros de cadena a los 3 parámetros largos originales para manejar esto. fixedDelayString, fixedRateStringy initialDelayStringahora también están disponibles.

@Scheduled(fixedDelayString = "${my.fixed.delay.prop}")
public void readLog() {
        ...
}
Mark-A
fuente
3
@Avi Esta respuesta llega tres años después de la pregunta del OP. En el momento de la pregunta (y la respuesta aceptada) esta característica no existía.
medveshonok117
@ medveshonok117 Lo tengo. Gracias
Avi
51

Puede usar la @Scheduledanotación, pero solo junto con el cronparámetro:

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

Su intervalo de 5 segundos podría expresarse como "*/5 * * * * *". Sin embargo, según tengo entendido, no puede proporcionar menos de 1 segundo de precisión.

kan
fuente
9
La expresión cron que ha mostrado es equivalente a fixedRate, que es diferente a fixedDelay
codebox
4

En Spring Boot 2, podemos usar Spring Expression Language (SpPL) para las @Scheduledpropiedades de anotación:

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

El application.propertiesarchivo se verá así:

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

Eso es. Aquí hay un artículo que explica la programación de tareas en detalle.

atacomsian
fuente
1

Supongo que puede convertir el valor usted mismo definiendo un bean. No lo he intentado , pero supongo que un enfoque similar al siguiente podría ser útil para usted:

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

dónde:

<bean id="YourConfigurationBean" class="...">
         <property name="stringValue" value="5000"/>
</bean>
Grzegorz Oledzki
fuente
Gracias, eso suena como una forma, pero para ser honesto, esperaba una solución más elegante ("elástica") :-)
ngeek
2
Desafortunadamente, esto no funcionará, ya que el atributo de anotación @Scheduled fixedDelay requiere que se asigne una constante (larga).
ngeek
Ah, eso es correcto. Entonces supongo que no puedes hacerlo con la @Scheduledanotación.
Grzegorz Oledzki