先上一段前同事写的代码,看完下面的代码,你可能会想,我滴天啊,这个类上是不是少了个@EnableScheduling注解,不然这个定时任务怎执行呢?然并卵,这个定时任务真的执行了,我僵住了。为了找这个原因,百度,谷歌我都搜了好多遍,都没能找到如何在不加@EnableScheduling的前提下进行定时任务。靠人不如靠自己,源码走起。
@Service("visitcountService")
public class VisitCountService implements VisitCountManager {
@Scheduled(cron = "0 0/6 * * * ?")
public void save() throws Exception {
}
}
首先我们看@EnableScheduling的源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
}
# 它import了SchedulingConfiguration.class,这里无法看出端倪,继续跟进
SchedulingConfiguration,如下所示
@Configuration
public class SchedulingConfiguration {
public SchedulingConfiguration() {
}
@Bean(
name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"}
)
@Role(2)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}
# 由此可以看出EnableScheduling其实是个Configuration配置类,关于@Configuration我解释下
@Configuration:配置在类上面,相当于整个类是<beans>包围的配置文件,里面加入一些子配置
信息,如<bean>标签,这样子,通过引入该配置文件,可以读取到该配置文件下面的所有bean
# 一般是这样使用的,在JavaConfigB配置类中,注册了一个Car的Bean
@Configuration
public class JavaConfigB {
@Bean
public Car getToyota(){
return new Volkswagen();
}
}
# 从上面的结果可以初步推断出,@EnableScheduling其实就是相当于xml中的beans标签,它会
对配置在该beans中的类进行检查,扫码这些类中的@Scheduled标签,最后进行定时任务的开启。
最后的代码测试也佐证了我这一想法,如下所示:
@Component
@EnableScheduling
public class QuartzTask {
@Resource(name="visitCountService");
public VisitCountManager visitCountService;
}
@Service("visitcountService")
public class VisitCountService implements VisitCountManager {
@Scheduled(cron = "0 0/6 * * * ?")
public void save() throws Exception {
}
}
# 该定时器会执行
# 如果我把VisitCountManager的@Resource给去掉,则定时器不会执行
这个代码写得,真的是,我这暴脾气,这样没去跟下源码的人怎么知道@EnableScheduling的定时是这样的,叫其他人怎么维护,当时我和其他同事看着代码的时候一头雾水,远离这种代码,从你我做起
参考博客: