How to change Spring's @Scheduled fixedDelay at runtime

前端 未结 5 1884
予麋鹿
予麋鹿 2020-11-30 03:00

I have a requirement to run a batch job at a fixed interval and have the ability to change the time of this batch job at runtime. For this I came across @Scheduled annotatio

5条回答
  •  一向
    一向 (楼主)
    2020-11-30 03:58

    create interface , something like that:

        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);
    }
    

    Next, lets implement Trigger interface that is located at org.springframework.scheduling in the spring-context project.

    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);
        }
    }
    

    now configuration:

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

    and usage:

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

提交回复
热议问题