복붙노트

[SPRING] Spring에서 예약 된 작업을 조건부로 활성화 또는 비활성화하는 방법은 무엇입니까?

SPRING

Spring에서 예약 된 작업을 조건부로 활성화 또는 비활성화하는 방법은 무엇입니까?

@Scheduled 주석을 사용하여 봄에 cron 스타일 패턴으로 예약 된 작업을 정의하고 있습니다.

cron 패턴은 구성 등록 정보 파일에 저장됩니다. 실제로 기본 설정 하나와 환경 의존적 인 하나의 프로필 설정 (예 : dev, test, 고객 1, 고객 2 등)의 두 가지 속성 파일이 있으며 기본값 중 일부를 무시합니다.

내 봄 컨텍스트에서 $ {} 스타일 자리 표시자를 사용하여 속성 파일에서 값을 가져올 수있는 속성 자리 표시 자 bean을 구성했습니다.

작업 bean은 다음과 같습니다.

@Component
public class ImagesPurgeJob implements Job {

    private Logger logger = Logger.getLogger(this.getClass());

    @Override
    @Transactional(readOnly=true)
    @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}")
    public void execute() {
        //Do something
            //can use DAO or other autowired beans here
    }
}

내 컨텍스트의 관련 부분 XML :

<!-- Enable configuration of scheduled tasks via annotations -->
    <task:annotation-driven/>

<!-- Load configuration files and allow '${}' style placeholders -->
    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config/default-config.properties</value>
                <value>classpath:config/environment-config.properties</value>
            </list>
        </property>
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="ignoreResourceNotFound" value="false"/>
    </bean>

나는 이것을 정말로 좋아한다. 최소한의 XML만으로 간단하고 깨끗합니다.

그러나 나는 한가지 더 요구 사항을 가지고 있습니다 : 어떤 경우에는 이러한 일자리들이 완전히 무력화 될 수 있습니다.

그래서 Spring을 관리하기 전에 수동으로 생성했고 config 파일에 cron 매개 변수와 함께 부울 매개 변수가있어 작업을 활성화할지 여부를 지정합니다.

jobs.mediafiles.imagesPurgeJob.enable=true or false
jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ?

Spring에서이 매개 변수를 사용하여이 설정 매개 변수에 따라 빈을 조건부로 만들거나 간단히 무시할 수 있습니까?

하나의 확실한 해결 방법은 결코 평가할 수없는 cron 패턴을 정의하는 것이므로 작업이 실행되지 않습니다. 하지만 빈은 여전히 ​​생성 될 것이고 설정은 약간 애매해질 것이므로 더 나은 해결책이 있어야한다고 생각합니다.

해결법

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

    1.

    @Component
    public class ImagesPurgeJob implements Job {
    
        private Logger logger = Logger.getLogger(this.getClass());
    
        @Value("${jobs.mediafiles.imagesPurgeJob.enable}")
        private boolean imagesPurgeJobEnable;
    
        @Override
        @Transactional(readOnly=true)
        @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}")
        public void execute() {
    
             //Do something
            //can use DAO or other autowired beans here
            if(imagesPurgeJobEnable){
    
                Do your conditional job here...
    
            }
        }
    }
    
  2. ==============================

    2.Spring Boot는 @ConditionalOnProperty를 제공하는데, Spring Boot를 사용한다면 완벽 할 것입니다. 이 주석은 Spring 4.0.0에서 소개 된 @Conditional의 특수화입니다.

    Spring Boot는 @ConditionalOnProperty를 제공하는데, Spring Boot를 사용한다면 완벽 할 것입니다. 이 주석은 Spring 4.0.0에서 소개 된 @Conditional의 특수화입니다.

    Spring Boot가 아닌 "regular"Spring을 사용한다고 가정하면 Spring Boot의 @ConditionalOnProperty를 모방하는 @ Condition으로 사용할 조건 구현을 직접 만들 수 있습니다.

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

    3.조건에 따라 스케줄 메소드를 서비스 수로 그룹화하고 다음과 같이 초기화 할 수 있습니다.

    조건에 따라 스케줄 메소드를 서비스 수로 그룹화하고 다음과 같이 초기화 할 수 있습니다.

    @Service
    @ConditionalOnProperty("yourConditionPropery")
    public class SchedulingService {
    
    @Scheduled
    public void task1() {...}
    
    @Scheduled
    public void task2() {...}
    
    }
    
  4. ==============================

    4.귀하의 질문에 콩의 실제 생성 조건을 설명합니다. Spring 3.1 이상을 사용하고 있다면 @Profile을 사용하여이 매개 변수로 쉽게이 작업을 수행 할 수 있습니다.

    귀하의 질문에 콩의 실제 생성 조건을 설명합니다. Spring 3.1 이상을 사용하고 있다면 @Profile을 사용하여이 매개 변수로 쉽게이 작업을 수행 할 수 있습니다.

    http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html에서 설명서를 참조하십시오.

  5. ==============================

    5.

    @Component
    public class CurrencySyncServiceImpl implements CurrencySyncService {
    
        private static Boolean isEnableSync;
        /**
         * Currency Sync FixedDelay in minutes
         */
        private static Integer fixedDelay;
    
        @Transactional
        @Override
        @Scheduled(fixedDelayString = "#{${currency.sync.fixedDelay}*60*1000}")
        public void sync() {
            if(CurrencySyncServiceImpl.isEnableSync) {
                //Do something
                //you can use DAO or other autowired beans here.
            }
        }
    
        @Value("${currency.sync.fixedDelay}")
        public void setFixedDelay(Integer fixedDelay) {
            CurrencySyncServiceImpl.fixedDelay = fixedDelay;
        }
    
        @Value("${currency.sync.isEnable}")
        public void setIsEnableSync(Boolean isEnableSync) {
            CurrencySyncServiceImpl.isEnableSync = isEnableSync;
        }
    }
    
  6. ==============================

    6.속성에서 @EnableScheduling을 토글하고자하는 경우 @EnableScheduling 주석을 구성 클래스로 이동하고 다음과 같이 @ConditionalOnProperty를 사용하여 Spring Boot에서이 작업을 수행 할 수 있습니다.

    속성에서 @EnableScheduling을 토글하고자하는 경우 @EnableScheduling 주석을 구성 클래스로 이동하고 다음과 같이 @ConditionalOnProperty를 사용하여 Spring Boot에서이 작업을 수행 할 수 있습니다.

    @Configuration
    @EnableScheduling
    @ConditionalOnProperty(prefix = "com.example.scheduling", name="enabled", havingValue="true", matchIfMissing = true)
    public class SchedulingConfiguration {
    
    }
    

    그러면 응용 프로그램의 일정이 비활성화됩니다. 이 방법은 응용 프로그램을 한 번 실행하거나 시작 방법에 따라 예약 할 수있는 상황에서 유용 할 수 있습니다.

    여기에 wilkinsona의 의견 : https://github.com/spring-projects/spring-boot/issues/12682

  7. ==============================

    7.내 대답은 해킹 알지만, 실행하지 않는 유효한 cron 표현식을 주면 (환경 특정 구성에서) 문제를 해결할 수 있습니다. Quartz : 결코 실행되지 않는 Cron 표현식

    내 대답은 해킹 알지만, 실행하지 않는 유효한 cron 표현식을 주면 (환경 특정 구성에서) 문제를 해결할 수 있습니다. Quartz : 결코 실행되지 않는 Cron 표현식

  8. ==============================

    8.또한 조건에 따라 Bean을 만들 수 있으며 Bean은 Scheduled 메소드를 가질 수 있습니다.

    또한 조건에 따라 Bean을 만들 수 있으며 Bean은 Scheduled 메소드를 가질 수 있습니다.

    @Component
    @Configuration
    @EnableScheduling
    public class CustomCronComponent {
        @Bean
        @ConditionalOnProperty(value = "my.cron.enabled", matchIfMissing = true, havingValue = "true")
        public MyCronTask runMyCronTask() {
            return new MyCronTask();
        }
    }
    

    @Component
    public class MyCronTask {
        @Scheduled(cron = "${my.cron.expression}")
        public void run() {
            String a = "";
        }
    }
    
  9. from https://stackoverflow.com/questions/18406713/how-to-conditionally-enable-or-disable-scheduled-jobs-in-spring by cc-by-sa and MIT license