que mvc modelo modelandview formulario español ejemplo arquitectura anotaciones java spring scheduled-tasks quartz-scheduler

java - modelo - spring mvc español



Cómo cambiar el Retardo @ fijo programado de Spring en tiempo de ejecución (4)

AFAIK la API de Spring no le permitirá acceder a las partes internas que necesita para cambiar el activador. Pero en su lugar podrías configurar manualmente los beans:

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="jobDetail" /> <property name="startDelay" value="10000" /> <property name="repeatInterval" value="50000" /> </bean> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="simpleTrigger" /> </list> </property> </bean>

Luego, como se documenta en SchedulerFactoryBean:

Para el registro dinámico de trabajos en tiempo de ejecución, use una referencia de bean a este SchedulerFactoryBean para obtener acceso directo al Quartz Scheduler ( org.quartz.Scheduler ). Esto le permite crear nuevos trabajos y activadores, y también controlar y monitorear todo el Programador.

Tengo un requisito para ejecutar un trabajo por lotes en un intervalo fijo y tengo la capacidad de cambiar la hora de este trabajo por lotes en tiempo de ejecución. Para esto me encontré con la anotación @Scheduled provista bajo Spring framework. Pero no estoy seguro de cómo cambiaría el valor de fixedDelay en tiempo de ejecución. Hice algo de googlear, pero no encontré nada útil.


En el arranque de primavera, puede utilizar una propiedad de aplicación directamente!

Por ejemplo:

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000") private void process() { // your impl here }

Tenga en cuenta que también puede tener un valor predeterminado en caso de que la propiedad no esté definida, por ejemplo, para tener un valor predeterminado de "60" (segundos):

@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")

Otras cosas que descubrí:

  • el método debe ser nulo
  • El método no debe tener parámetros.
  • el método puede ser private

Encontré poder usar private visibilidad private y lo usé de esta manera:

@Service public class MyService { public void process() { // do something } @Scheduled(fixedDelayString = "${my.poll.fixed.delay.seconds}000") private void autoProcess() { process(); } }

Al ser private , el método programado puede ser local para su servicio y no formar parte de la API de su Servicio.

Además, este enfoque permite que el método process() devuelva un valor, que un método @Scheduled no puede. Por ejemplo, su método process() puede verse como:

public ProcessResult process() { // do something and collect information about what was done return processResult; }

para proporcionar alguna información sobre lo que sucedió durante el procesamiento.


crear interfaz, algo por el estilo:

public abstract class DynamicSchedule{ /** * Delays scheduler * @param milliseconds - the time to delay scheduler. */ abstract void delay(Long milliseconds); /** * Decreases delay period * @param milliseconds - the time to decrease delay period. */ abstract void decreaseDelayInterval(Long milliseconds); /** * Increases delay period * @param milliseconds - the time to increase dela period */ abstract void increaseDelayInterval(Long milliseconds); }

A continuación, implementemos la interfaz de Trigger que se encuentra en org.springframework.scheduling en el proyecto de contexto de primavera.

import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import java.util.Date; import java.util.concurrent.ScheduledFuture; public class CustomDynamicSchedule extends DynamicSchedule implements Trigger { private TaskScheduler taskScheduler; private ScheduledFuture<?> schedulerFuture; /** * milliseconds */ private long delayInterval; public CustomDynamicSchedule(TaskScheduler taskScheduler) { this.taskScheduler = taskScheduler; } @Override public void increaseDelayInterval(Long delay) { if (schedulerFuture != null) { schedulerFuture.cancel(true); } this.delayInterval += delay; schedulerFuture = taskScheduler.schedule(() -> { }, this); } @Override public void decreaseDelayInterval(Long delay) { if (schedulerFuture != null) { schedulerFuture.cancel(true); } this.delayInterval += delay; schedulerFuture = taskScheduler.schedule(() -> { }, this); } @Override public void delay(Long delay) { if (schedulerFuture != null) { schedulerFuture.cancel(true); } this.delayInterval = delay; schedulerFuture = taskScheduler.schedule(() -> { }, this); } @Override public Date nextExecutionTime(TriggerContext triggerContext) { Date lastTime = triggerContext.lastActualExecutionTime(); return (lastTime == null) ? new Date() : new Date(lastTime.getTime() + delayInterval); } }

ahora configuracion:

@Configuration public class DynamicSchedulerConfig { @Bean public CustomDynamicSchedule getDinamicScheduler() { ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.initialize(); return new CustomDynamicSchedule(threadPoolTaskScheduler); } }

y uso:

@EnableScheduling @Component public class TestSchedulerComponent { @Autowired private CustomDynamicSchedule dynamicSchedule; @Scheduled(fixedDelay = 5000) public void testMethod() { dynamicSchedule.delay(1000l); dynamicSchedule.increaseDelayInterval(9000l); dynamicSchedule.decreaseDelayInterval(5000l); } }