Actuellement j'ai ceci:
@Scheduled(fixedRate=5000)
public void getSchedule(){
System.out.println("in scheduled job");
}
Je pourrais changer cela pour utiliser une référence à une propriété
@Scheduled(fixedRate=${myRate})
public void getSchedule(){
System.out.println("in scheduled job");
}
Cependant, je dois utiliser une valeur obtenue par programme pour que la planification puisse être modifiée sans redéployer l'application. Quel est le meilleur moyen? Je me rends compte que l'utilisation d'annotations peut ne pas être possible ...
En utilisant Trigger
, vous pouvez calculer le prochain temps d'exécution à la volée.
Quelque chose comme ça devrait faire l'affaire (adapté de Javadoc pour @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();
}
}
);
}
}
Aussi, vous pouvez utiliser cette approche 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
est entièrement configurable à l'exécution et peut être utilisé avec @Value
annotation.
vous pouvez gérer le redémarrage de la planification à l'aide de TaskScheduler et 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();
}
}
interface pour start stop:
public interface SchedulerObjectInterface {
void start();
void stop();
}
maintenant, vous pouvez arrêter et recommencer (redémarrer) Planification à l'aide de @Autowired SchedulerObjectInterface
Exemple de démarrage simplifié limité à des intervalles de secondes, de minutes et d’heures. L’intention de cet exemple est de démontrer le traitement conditionnel de deux propriétés, TimeUnit et interval.
Propriétés:
snapshot.time-unit=SECONDS
snapshot.interval=5
Méthode programmée:
@Scheduled(cron = "*/1 * * * * *")
protected void customSnapshotScheduler()
{
LocalDateTime now = LocalDateTime.now();
TimeUnit timeUnit = TimeUnit.valueOf(snapshotProperties.getSnapshot().getTimeUnit());
int interval = snapshotProperties.getSnapshot().getInterval();
if (TimeUnit.SECONDS == timeUnit
&& now.getSecond() % interval == 0)
{
this.camService.writeSnapshot(webcam.getImage());
}
if (TimeUnit.MINUTES == timeUnit
&& now.getMinute() % interval == 0)
{
this.camService.writeSnapshot(webcam.getImage());
}
if (TimeUnit.HOURS == timeUnit
&& now.getHour() % interval == 0)
{
this.camService.writeSnapshot(webcam.getImage());
}
}