복붙노트

[SPRING] 런타임시 스프링의 @Scheduled fixedDelay를 변경하는 방법

SPRING

런타임시 스프링의 @Scheduled fixedDelay를 변경하는 방법

고정 된 간격으로 배치 작업을 실행하고 런타임에이 배치 작업의 시간을 변경할 수있는 요구 사항이 있습니다. 이를 위해 @Scheduled annotation이 Spring 프레임 워크에서 제공되었다. 하지만 런타임에 fixedDelay의 값을 어떻게 바꿀 지 확신하지 못합니다. 나는 주변에 인터넷 검색을했지만 유용한 것을 찾지 못했습니다.

해결법

  1. ==============================

    1.트리거를 사용하여 다음 실행 시간을 동적으로 설정할 수 있습니다. 내 대답보기 :

    트리거를 사용하여 다음 실행 시간을 동적으로 설정할 수 있습니다. 내 대답보기 :

    프로그래밍 방식으로 Spring을 사용하여 작업 예약 (fixedRate를 동적으로 설정)

  2. ==============================

    2.봄 부팅시 응용 프로그램 속성을 직접 사용할 수 있습니다!

    봄 부팅시 응용 프로그램 속성을 직접 사용할 수 있습니다!

    예 :

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

    속성이 정의되지 않은 경우를 대비하여 기본값을 가질 수도 있습니다 (예 : 기본값 "60"(초)).

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

    내가 발견 한 다른 것들 :

    개인적 시야를 편리하게 사용할 수 있다는 것을 알게되었고 다음과 같이 사용했습니다.

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

    비공개이므로 예약 된 메소드는 서비스의 로컬 일 수 있으며 서비스의 API 일부가 될 수 없습니다.

    또한이 방법을 사용하면 process () 메서드가 @Scheduled 메서드가 사용할 수없는 값을 반환 할 수 있습니다. 예를 들어 process () 메소드는 다음과 같습니다.

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

    처리 중에 일어난 일에 대한 정보를 제공합니다.

  3. ==============================

    3.같은 인터페이스를 생성하십시오.

    같은 인터페이스를 생성하십시오.

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

    다음으로 스프링 컨텍스트 프로젝트에서 org.springframework.scheduling에 위치한 Trigger 인터페이스를 구현하도록합니다.

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

    지금 구성 :

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

    및 사용 :

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

    4.AFAIK 스프링 API는 트리거를 변경하는 데 필요한 내부 구조에 액세스 할 수 없도록합니다. 그러나 bean을 직접 수동으로 구성 할 수 있습니다.

    AFAIK 스프링 API는 트리거를 변경하는 데 필요한 내부 구조에 액세스 할 수 없도록합니다. 그러나 bean을 직접 수동으로 구성 할 수 있습니다.

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

    그런 다음 SchedulerFactoryBean에 문서화 된대로 :

  5. from https://stackoverflow.com/questions/15250928/how-to-change-springs-scheduled-fixeddelay-at-runtime by cc-by-sa and MIT license