本地启动关闭@Scheduled定时任务 | 注释掉@EnableScheduling无效

        • 0. 背景:
        • 1. 普通关闭:
        • 2. 注释掉@EnableScheduling无效,还会执行@Scheduled定时任务

0. 背景:

大量的@Scheduled定时任务,影响本地调试,控制台一直再跑

1. 普通关闭:

正常情况下,只要注释掉@EnableScheduling注解即可,原理就是:

  • 注释掉@EnableScheduling就不会@Import(SchedulingConfiguration.class)
  • 就不会注入ScheduledAnnotationBeanPostProcessor这个后置处理器
  • 这个后置处理器就是用来注册执行@Scheduled定时任务的
2. 注释掉@EnableScheduling无效,还会执行@Scheduled定时任务

这种情况要检查是否项目除启动类还有其它配置类用了@EnableScheduling注解

  • 检查有没有引入spring-session-data-redis依赖,RedisHttpSessionConfiguration内部bean使用了@EnableScheduling
  • 据说spring-boot-starter-actuator依赖也会有,但是我没找到

这种情况如何屏蔽掉定时任务呢?如下代码:

  • 在容器启动后,获取收集的的定时任务Set
  • 通过后置处理器的postProcessBeforeDestruction来移除任务,这样就不会执行了

@Component
public class ApplicationListenerImpl implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    private ScheduledAnnotationBeanPostProcessor beanPostProcessor;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 拿到所有的task(带包装)
        Set<ScheduledTask> tasks = beanPostProcessor.getScheduledTasks();
        Set<Object> rawTasks = new HashSet<>(tasks.size());
        for (ScheduledTask task : tasks) {
            Task t = task.getTask();
            Runnable runnableTemp = t.getRunnable();
            ScheduledMethodRunnable runnable = null;
            if (runnableTemp instanceof ScheduledMethodRunnable) {
                runnable = (ScheduledMethodRunnable) runnableTemp;
            }
            if (runnable == null) {
                continue;
            }

            Object taskObject = runnable.getTarget();
            // 将task所关联的对象放到Set中(就是带@Scheduled方法的类)
            rawTasks.add(taskObject);
        }
        // 调用postProcessBeforeDestruction()方法,将task移除并cancel
        for (Object obj : rawTasks) {
            beanPostProcessor.postProcessBeforeDestruction(obj, "scheduledTasks");
        }
        System.out.println("listener");
    }

也可以通过实现ApplicationRunner的方式
`
区别在于:ApplicationRunner、ApplicationListener区别

你可能感兴趣的:(其他,scheduled,定时任务,spring,task,关闭定时任务)