Spring task -- 定时任务源码解析

Task定时器

定义xml定时任务配置




    

  • 配置好xml后,Spring将其解析成为BeanDefinition

其中task:scheduled标签被解析为一个Task的具体实现类

Spring-Task结构图.png

调度执行入口:ContextLifecycleScheduledTaskRegistrar

    // ContextLifecycleScheduledTaskRegistrar
    // 在Bean初始化之后调度
    @Override
    public void afterSingletonsInstantiated() {
        scheduleTasks();
    }

    // ScheduledTaskRegistrar
    // 如果配置了相应的Tasks,则添加到Set scheduledTasks中
        protected void scheduleTasks() {
        // 初始化taskScheduler,如果没有配置task:scheduler,就会进行初始化
        if (this.taskScheduler == null) {
            this.localExecutor = Executors.newSingleThreadScheduledExecutor();
            this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
        }
        if (this.triggerTasks != null) {
            for (TriggerTask task : this.triggerTasks) {
                addScheduledTask(scheduleTriggerTask(task));
            }
        }
        if (this.cronTasks != null) {
            for (CronTask task : this.cronTasks) {
                addScheduledTask(scheduleCronTask(task));
            }
        }
        if (this.fixedRateTasks != null) {
            for (IntervalTask task : this.fixedRateTasks) {
                addScheduledTask(scheduleFixedRateTask(task));
            }
        }
        if (this.fixedDelayTasks != null) {
            for (IntervalTask task : this.fixedDelayTasks) {
                addScheduledTask(scheduleFixedDelayTask(task));
            }
        }
    }

下面以CronTask为例:

CronTask解析表达式为trigger
  • tips: Trigger被定义为决定一个任务的下一次执行时间
    /**
     * Create a new {@code CronTask}.
     * @param runnable the underlying task to execute
     * @param expression the cron expression defining when the task should be executed
     */
    public CronTask(Runnable runnable, String expression) {
        this(runnable, new CronTrigger(expression));
    }

    /**
     * Build a {@link CronTrigger} from the pattern provided in the default time zone.
     * @param expression a space-separated list of time fields, following cron
     * expression conventions
     */
    public CronTrigger(String expression) {
        this.sequenceGenerator = new CronSequenceGenerator(expression);
    }

    ···
    // 最后到CronSequenceGenerator进行解析
    private void doParse(String[] fields) {
        setNumberHits(this.seconds, fields[0], 0, 60);
        setNumberHits(this.minutes, fields[1], 0, 60);
        setNumberHits(this.hours, fields[2], 0, 24);
        setDaysOfMonth(this.daysOfMonth, fields[3]);
        setMonths(this.months, fields[4]);
        setDays(this.daysOfWeek, replaceOrdinals(fields[5], "SUN,MON,TUE,WED,THU,FRI,SAT"), 8);

        if (this.daysOfWeek.get(7)) {
            // Sunday can be represented as 0 or 7
            this.daysOfWeek.set(0);
            this.daysOfWeek.clear(7);
        }
    }

通过ReschedulingRunnable来完成调度;

  • (这里不谈EnterpriseConcurrentTriggerScheduler)
ReschedulingRunnable: 其父类DelegatingErrorHandlingRunnable implements 了 Runnable
    @Nullable
    public ScheduledFuture schedule() {
        synchronized (this.triggerContextMonitor) {
            this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
            if (this.scheduledExecutionTime == null) {
                return null;
            }
            long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
            this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
            // 下一次执行窗口调用this(ReschedulingRunnable)
            return this;
        }
    }

    @Override
    public void run() {
        Date actualExecutionTime = new Date();
        super.run();
        Date completionTime = new Date();
        synchronized (this.triggerContextMonitor) {
            Assert.state(this.scheduledExecutionTime != null, "No scheduled execution");
            this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
            if (!obtainCurrentFuture().isCancelled()) {
                schedule();
            }
        }
    }

参考:

Seaswalker的Spring-analysis:
github地址

你可能感兴趣的:(Spring task -- 定时任务源码解析)