SpringBoot的@Enable系列注解

708 阅读2分钟

SpringBoot利用 @Enable 系列注解引用新的功能. 写个document记录一波

介绍@Enable

用到这个注解的地方有很多,比较出名的 @EnableScheduling 算一个,用于其开启定时任务,如果没有使用该注解,就不能使用Spring提供定时任务的能力,即 Scheduled 注解提供的定时任务, 其功能等价于 Spring XML中命名空间为 <task:*> 部分.

一个小小的 @EnableScheduling 竟有如此本领. 先猜想一波它是怎么做的. 之前先回顾下 Spring 是怎么用的,在没有SpringBoot之前,我们都会在XML中配置 <task:*> 的用法,该配置会主动引入 TaskNamespaceHandler ,用来解析task部分的XML数据, 这个过程会引入 ScheduledAnnotationBeanPostProcessor ,它的工作就是在Bean初始化之后,判断Bean的方法是否具有 Scheduled 并且符合定时任务的规则,加入定时任务. 通过对 task 标签的回顾,可以很清楚的明白核心在于引入 ScheduledAnnotationBeanPostProcessor ,只要有了这个实例对象,那么被 Scheduled注解(前提是合规)的方法就可以被Spring定时调度了.

添加EnableScheduling注解

引入定时功能

@SpringBootApplication
@EnableScheduling
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

注解详情

相比平时的 Component , Service 注解多了一个 Import 注解,Import基本上就件名思义了. 引入一个或多个 Configuration 注解的类. 这里直接引入了 SchedulingConfiguration 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {

}

SchedulingConfiguration

hmmmm,引入了 ScheduledAnnotationBeanPostProcessor,后续就不许多言了.

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {

	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
		return new ScheduledAnnotationBeanPostProcessor();
	}
}

自定义@Enable

明白了上边的定时任务后,相比自定义一个出来已经不是难事了,核心还是在于 BeanPostProcessor ,它能够在初始化前和后分别对Bean做出一些处理.

表面上我们说的 Enable 注解,实际上它真正起作用的是 BeanPostProcessor ,如果看不明白这一层,那还得多看看.

问题

  • 如何使定时任务注解Scheduled生效?
  • 不使用@EnableScheduling还可以做到吗?
  • 你可以自定义一个注解实现Schedule相同的功能吗?
  • 通过这里此刻你可以想像到@Async详解是怎么工作的吗?