@EnableXXX这一类注解的作用:就是用来启用某一个功能的配置。启用某一功能,仅需要加上一个注解即可生效,可以使组建之间的相互依赖降低了耦合性。
-
- @EnableWebSecurity
- @EnableScheduling
- @EnableAsync
- @EnableWebMvc
- @EnableCaching
- @EnableAutoConfiguration
通常代码使用逻辑:以@EnableCaching为例,如果没有配置@EnableCaching,那么@Cacheable注解就不会生效。原因是:@EnableXXX通过相关逻辑,判断某个字段/方法/类上面是否存在相关的注解,如果存在,则让其生效。
@EnableScheduling实现逻辑
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Import({SchedulingConfiguration.class}) @Documented public @interface EnableScheduling { }
2.1 关键实现1:SchedulingConfiguration类定义
@Configuration( proxyBeanMethods = false ) @Role(2) public class SchedulingConfiguration { public SchedulingConfiguration() { } @Bean( name = {"org.springframework.context.annotation.internalScheduledAnnotationProcessor"} ) @Role(2) public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() { return new ScheduledAnnotationBeanPostProcessor(); } }
ScheduledAnnotationBeanPostProcessor.java,实现了多个接口
public class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean { public static final String DEFAULT_TASK_SCHEDULER_BEAN_NAME = "taskScheduler"; protected final Log logger = LogFactory.getLog(this.getClass()); private final ScheduledTaskRegistrar registrar; @Nullable private Object scheduler; @Nullable private StringValueResolver embeddedValueResolver; @Nullable private String beanName; @Nullable private BeanFactory beanFactory; @Nullable private ApplicationContext applicationContext; private final Set<Class<?>> nonAnnotatedClasses = Collections.newSetFromMap(new ConcurrentHashMap(64)); private final Map<Object, Set<ScheduledTask>> scheduledTasks = new IdentityHashMap(16);
1、实现了继承自:BeanPostProcessor::ProcessAfterInitialization(Object bean, String beanName) 实现,判断方法上面是否存在@Scheduled注解
public Object postProcessAfterInitialization(Object bean, String beanName) { if (!(bean instanceof AopInfrastructureBean) && !(bean instanceof TaskScheduler) && !(bean instanceof ScheduledExecutorService)) { Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean); if (!this.nonAnnotatedClasses.contains(targetClass) && AnnotationUtils.isCandidateClass(targetClass, Arrays.asList(Scheduled.class, Schedules.class))) { Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (method) -> { Set<Scheduled> scheduledAnnotations = AnnotatedElementUtils.getMergedRepeatableAnnotations(method, Scheduled.class, Schedules.class); return !scheduledAnnotations.isEmpty() ? scheduledAnnotations : null; }); if (annotatedMethods.isEmpty()) { this.nonAnnotatedClasses.add(targetClass); if (this.logger.isTraceEnabled()) { this.logger.trace("No @Scheduled annotations found on bean class: " + targetClass); } } else { annotatedMethods.forEach((method, scheduledAnnotations) -> { scheduledAnnotations.forEach((scheduled) -> { this.processScheduled(scheduled, method, bean); }); }); if (this.logger.isTraceEnabled()) { this.logger.trace(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName + "': " + annotatedMethods); } } } return bean; } else { return bean; } }
如果存在@Scheduled注解,则在后续处理中,继续解析@Scheduled注解中各种关于定时周期的定义,如fixRate(下图),放入定时任务(最终封装成 java.util.concurrent.ScheduledFuture)执行。
2、实现了继承自DisposableBean::destroy()方法,最终调用线程池线程(ScheduledFuture::cacel) 和线程池的关闭(ScheduledExecutorService::shutdownNow)
public void destroy() { synchronized(this.scheduledTasks) { Collection<Set<ScheduledTask>> allTasks = this.scheduledTasks.values(); Iterator var3 = allTasks.iterator(); label25: while(true) { if (var3.hasNext()) { Set<ScheduledTask> tasks = (Set)var3.next(); Iterator var5 = tasks.iterator(); while(true) { if (!var5.hasNext()) { continue label25; } ScheduledTask task = (ScheduledTask)var5.next(); task.cancel(); } } this.scheduledTasks.clear(); break; } } this.registrar.destroy(); }
2.2 关键实现2:@Import注解定义
实现的功能:加载它自己对应的配置类,然后启动他的功能。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Import { Class<?>[] value(); }
@Import 注解导入的类 有三种,分别是:
1、ImportSelector: 比如@EnableAsync
@Import({AsyncConfigurationSelector.class}) public @interface EnableAsync {
2、ImportBeanDefinitionRegistrar
3、普通类:会当作为配置类去处理。
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({DelegatingWebMvcConfiguration.class}) public @interface EnableWebMvc { }