How to conditionally enable or disable scheduled jobs in Spring?

前端 未结 11 1384
轻奢々
轻奢々 2020-11-28 07:26

I am defining scheduled jobs with cron style patterns in Spring, using the @Scheduled annotation.

The cron pattern is stored in a config properties file

11条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-28 07:49

    Please see my answer in another question. I think this is the best way to solve it. How to stop a scheduled task that was started using @Scheduled annotation?

    Define a custom annotation like below.

    @Documented
    @Retention (RUNTIME)
    @Target(ElementType.TYPE)
    public @interface ScheduledSwitch {
        // do nothing
    }
    

    Define a class implements org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.

    public class ScheduledAnnotationBeanPostProcessorCustom 
        extends ScheduledAnnotationBeanPostProcessor {
    
        @Value(value = "${prevent.scheduled.tasks:false}")
        private boolean preventScheduledTasks;
    
        private Map beans = new HashMap<>();
    
        private final ReentrantLock lock = new ReentrantLock(true);
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            ScheduledSwitch switch = AopProxyUtils.ultimateTargetClass(bean)
                .getAnnotation(ScheduledSwitch.class);
            if (null != switch) {
                beans.put(bean, beanName);
                if (preventScheduledTasks) {
                    return bean;
                }
            }
            return super.postProcessAfterInitialization(bean, beanName);
        }
    
        public void stop() {
            lock.lock();
            try {
                for (Map.Entry entry : beans.entrySet()) {
                    postProcessBeforeDestruction(entry.getKey(), entry.getValue());
                }
            } finally {
                lock.unlock();
            }
        }
    
        public void start() {
            lock.lock();
            try {
                for (Map.Entry entry : beans.entrySet()) {
                    if (!requiresDestruction(entry.getKey())) {
                        super.postProcessAfterInitialization(
                            entry.getKey(), entry.getValue());
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    
    }
    

    Replace ScheduledAnnotationBeanPostProcessor bean by the custom bean in configuration.

    @Configuration
    public class ScheduledConfig {
    
        @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public ScheduledAnnotationBeanPostProcessor scheduledAnnotationBeanPostProcessor() {
            return new ScheduledAnnotationBeanPostProcessorCustom();
        }
    
    }
    

    Add @ScheduledSwitch annotation to the beans that you want to prevent or stop @Scheduled tasks.

提交回复
热议问题