SpringBoot定时任务

2019-10-10  本文已影响0人  二哥很猛
  • 在SpringBoot项目中只需要添加@EnableScheduling即可开启定时任务,在方法添加@Scheduled注解即可实现固定周期某些方法.
  • @EnableScheduling注解中引入了SchedulingConfiguration配置,而该配置注册了一个名为ScheduledAnnotationBeanPostProcessor的bean
  • 看到BeanPostProcessor就大致知道该类用于Bean实例化或初始化前后的处理类,以下是该类实现的接口
//核心实现接口MergedBeanDefinitionPostProcessor
public class ScheduledAnnotationBeanPostProcessor
        implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor,
        Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware,
        SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean {
}

该类主要处理业务的方法是postProcessAfterInitialization,finishRegistration,processScheduled

postProcessAfterInitialization

public Object postProcessAfterInitialization(final Object bean, String beanName) {
    Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
       
    if (!this.nonAnnotatedClasses.contains(targetClass)) {
                //查找类中包含Scheduled或Schedules注解的方法
        Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
                (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
                    Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
                            method, Scheduled.class, Schedules.class);
                    return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
                });
        if (annotatedMethods.isEmpty()) {
            this.nonAnnotatedClasses.add(targetClass);
            if (logger.isTraceEnabled()) {
                logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
            }
        }
        else {
            // Non-empty set of methods
      //将包含@Scheduled或@Schedules注解的方法按类型包装成Task并交由ScheduledTaskRegistrar处理
            annotatedMethods.forEach((method, scheduledMethods) ->
                    scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
            if (logger.isDebugEnabled()) {
                logger.debug(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
                        "': " + annotatedMethods);
            }
        }
    }
    return bean;
}

processScheduled

String cron = scheduled.cron();
if (StringUtils.hasText(cron)) {
    String zone = scheduled.zone();
    if (this.embeddedValueResolver != null) {
        cron = this.embeddedValueResolver.resolveStringValue(cron);
        zone = this.embeddedValueResolver.resolveStringValue(zone);
    }
    if (StringUtils.hasLength(cron)) {
        Assert.isTrue(initialDelay == -1, "'initialDelay' not supported for cron triggers");
        processedSchedule = true;
        TimeZone timeZone;
        if (StringUtils.hasText(zone)) {
            timeZone = StringUtils.parseTimeZoneString(zone);
        }
        else {
            timeZone = TimeZone.getDefault();
        }
        tasks.add(this.registrar.scheduleCronTask(new CronTask(runnable, new CronTrigger(cron, timeZone))));
    }
}

题外话

上一篇 下一篇

猜你喜欢

热点阅读