java - scheduled - Programar un trabajo con Spring mediante programación(con fixedRate establecido dinámicamente)
spring boot scheduled task example (3)
También puedes usar este enfoque simple:
private int refreshTickNumber = 10;
private int tickNumber = 0;
@Scheduled(fixedDelayString = "${some.rate}")
public void nextStep() {
if (tickNumber < refreshTickNumber) {
tickNumber++;
return;
}
else {
tickNumber = 0;
}
// some code
}
refreshTickNumber
es totalmente configurable en tiempo de ejecución y se puede usar con la anotación @Value
.
Actualmente tengo esto:
@Scheduled(fixedRate=5000)
public void getSchedule(){
System.out.println("in scheduled job");
}
Podría cambiar esto para usar una referencia a una propiedad
@Scheduled(fixedRate=${myRate})
public void getSchedule(){
System.out.println("in scheduled job");
}
Sin embargo, necesito usar un valor obtenido programáticamente para que el cronograma pueda cambiarse sin volver a implementar la aplicación. ¿Cuál es la mejor manera? Me doy cuenta de que el uso de anotaciones puede no ser posible ...
Usando un Trigger
puedes calcular el siguiente tiempo de ejecución sobre la marcha.
Algo como esto debería hacer el truco (adaptado de Javadoc para @EnableScheduling
):
@Configuration
@EnableScheduling
public class MyAppConfig implements SchedulingConfigurer {
@Autowired
Environment env;
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
taskRegistrar.addTriggerTask(
new Runnable() {
@Override public void run() {
myBean().getSchedule();
}
},
new Trigger() {
@Override public Date nextExecutionTime(TriggerContext triggerContext) {
Calendar nextExecutionTime = new GregorianCalendar();
Date lastActualExecutionTime = triggerContext.lastActualExecutionTime();
nextExecutionTime.setTime(lastActualExecutionTime != null ? lastActualExecutionTime : new Date());
nextExecutionTime.add(Calendar.MILLISECOND, env.getProperty("myRate", Integer.class)); //you can get the value from wherever you want
return nextExecutionTime.getTime();
}
}
);
}
}
puede administrar la programación de reinicio usando TaskScheduler y ScheduledFuture:
@Configuration
@EnableScheduling
@Component
public class CronConfig implements SchedulingConfigurer , SchedulerObjectInterface{
@Autowired
private ScheduledFuture<?> future;
@Autowired
private TaskScheduler scheduler;
@Bean
public SchedulerController schedulerBean() {
return new SchedulerController();
}
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
@Override
public void start() {
future = scheduler.schedule(new Runnable() {
@Override
public void run() {
//System.out.println(JOB + " Hello World! " + new Date());
schedulerBean().schedulerJob();
}
}, new Trigger() {
@Override public Date nextExecutionTime(TriggerContext triggerContext) {
Calendar nextExecutionTime = new GregorianCalendar();
Date lastActualExecutionTime = triggerContext.lastActualExecutionTime();
nextExecutionTime.setTime(convertExpresssiontoDate());//you can get the value from wherever you want
return nextExecutionTime.getTime();
}
});
}
@Override
public void stop() {
future.cancel(true);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// TODO Auto-generated method stub
start();
}
}
interfaz para iniciar parada:
public interface SchedulerObjectInterface {
void start();
void stop();
}
ahora puede detener y comenzar de nuevo (reiniciar) Programando usando @Autowired SchedulerObjectInterface