搜索
简帛阁>技术文章>SpringBoot 1.X 不加@EnableScheduling也能跑-问题排查

SpringBoot 1.X 不加@EnableScheduling也能跑-问题排查

文章目录

      • 一、说明
      • 二、问题
        • 相关代码
      • 三、排查-看源码
        • 1. @Scheduled
        • 2. @EnableScheduling
      • 四、排查-网络解答
        • 新版本是否存在这个问题
      • 五、 结论
      • 六、参考资料

一、说明

版本号:SpringBoot 1.5.8.RELEASE
读者基础:用过SpringBoot定时任务

二、问题

启动类上面没有加上@EnableScheduling,只是在方法里面声明了一个@Scheduled,但是这个方法是有效的,是能够定时运行的。

相关代码

代码如下,这个是抽象类,它的子类的定时任务都可以正常运行。(并没有加@EnableScheduling)

01

三、排查-看源码

带着疑惑看看源码, 看下这个@EnableScheduling和@Schedule是如何配合的。

1. @Scheduled

02
从@Scheduled可以看出注解如果需要被执行,是需要这个ScheduledAnnotationBeanPostProcessor对象的。
而这个对象的生成有三种方法。

第一种:自己手动创建。
第二种:通过这个task:annotation-driven/ XML标签。
第三种:使用@EnableScheduling注解。

生成这个PostProcessor对象有以上三种方法。但是我的代码里面这上面的三种方式我都没有实现。所以并不是因为我自己的代码自己创建了对象,而使得定时任务可以运行的。于是我就再看看@EnableScheduling这个注解,看有没有什么特别的地方。

2. @EnableScheduling

03
看源码注释可以看出,这个EnableScheduling的作用和前面的XML标签是一样的,是一个开关,用来开启定时任务的。
04

再看看这里面导入了一个SchedulingConfiguration.class。点进去看一下,实际上他也是注册一个ScheduleAnnotationBeanPostProcessor对象,来处理@Scheduled注解。

上面的源码能够让我们知道@EnableScheduling和@Scheduled的关系。不过并无法回答为什么代码里面不写@EnableScheduling也能运行的原因。于是上网搜索。

四、排查-网络解答

通过网上搜索答案,在Springboot的github项目上,找到了这样的一个issued。
05

说的是actuator这个依赖里的MetriExportAutoConfiguration包含了EnableScheduling这个注解
于是我去看看源码,目前我的这个1.5.8版本的actuator确实如此。
06
07
为了验证是否确实是这个问题导致,我把actuator的依赖去掉,果然,我把actuator去掉后,定时任务不会执行了

所以能够锁定这个问题是由于

这个版本(1.5.8)actuator的 MetricExportAutoConfiguration包含了
@EnableScheduling,所以就算我们在自己的代码里面没有写这个注解,实际上定时任务也能够运行。

那这个不太合理,会存在一个问题。假设在一个项目里面,我想关闭掉原先在运行的定时任务,于是我把@EnableScheduling的注解去掉了,以为万事大吉。结果还是一样在运行。

新版本是否存在这个问题

同样在这个issued里面,Spring组织的成员Snicoll说明了,在新版本的SpringBoot 2.X就不存在这个问题了。
07
验证一下Snicoll的说法。
我下载了一个2.X版本的SpringBoot,选择了2.1.4.RELEASE这个版本。
已经找不到这个MetricExportAutoConfiguration类了。和这个类名最匹配的是这个AppOpticsMetricsExportAutoConfiguration类。

08
09
确实没有@EnableScheduling。
代码运行起来后,若我们没有添加@EnableScheduling,定时任务是不会运行的。

五、 结论

1.5.8版本的SpringBoot不需要写@EnableScheduling也能够运行定时任务的原因是actuator里面有一个配置类(MetricExportAutoConfiguration),它已经声明了这个注解。这个问题在SpringBoot 2.X之后修复了。

六、参考资料

  1. Spring不加@EnableScheduling

  2. Spring-boot scheduler runs without @EnableScheduling annotation

  3. MetricExportAutoConfiguration contains EnableScheduling annotation

项目开发中经常需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息。Spring为我们提供了异步执行任务调度的方式,提供TaskExecutor、TaskScheduler接口。Sp
springboot:计划任务@EnableScheduling和@Scheduled@Scheduled中的参数说明@Scheduled(fixedRate2000):上一次开始执行时间点后2秒再次
springboot:@EnableScheduling开启计划任务支持,@Scheduled计划任务声明1packagech2scheduler2;23//日期转换方式4importjavatext
spring中@Scheduled@EnableScheduling这2个注解,可以用来快速开发定时器,使用特别的简单。如何使用?用法1、需要定时执行的方法上加上@Scheduled注解,这个注解中可
现在使用springsession默认使用了redis缓存我们来看一下这个注解:@EnableRedisHttpSession再往里面看所以其实是springsession+redis的组合开启了默认
检查下springboot的启动类是否开启扫描@SpringBootApplication@ComponentScan(basePackages{comzhangpuspringboot})另外spr
1|1简介最近基于最新的Activiti7配置了SpringBoot2。简单上手使用了一番。发现市面上解决Activiti7的教程很少,采坑也比较多,在Activiti6配置数据源和Activiti7
1前言通过指定接口,重写指定方法,可以在Bean对应的生命周期方法中执行相应的程序2测试本文将分析几个Bean对象,为它们设置优先级(通过@Order),然后再打断点调试,测试各种生命周期方法的运行的
一)首先说明xia@requestBody与@requestParam的区别spring的RequestParam注解接收的参数是来自于requestHeader中,即请求头。都是用来获取请求路径(u
一、Rest简介从下面的URL风格可以看出,我们针对用户的不同操作,URL都是相同的,我们只是通过HTTP的请求方式来确定对user进行增、删、改、查URLHTTP请求方式具体操作/user/1POS