Insight spring @Scheduled 解析过程

接着上一篇<task:annotation-driven>解析,Insight @Scheduled 解析。

1、@Scheduled注解方法的加载

// bean 初始化后触发callback,ScheduledAnnotationBeanPostProcessor完成@Scheduled 的处理
// 参考InitializingBean's afterPropertiesSet
public Object postProcessAfterInitialization(final Object bean, String beanName) {
    // ...
    ReflectionUtils.doWithMethods(targetClass, new MethodCallback() {
    	public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
    		Scheduled scheduled = AnnotationUtils.getAnnotation(method, Scheduled.class);
    		if (scheduled != null) {
    			processScheduled(scheduled, method, bean);
    			annotatedMethods.add(method);
    		}
    	}
    });
    // ...
    return bean;
}
2、 @ Scheduled注解方法的处理

根据Scheduled属性构造不同类型的Task(triggerTasks、cronTasks、fixedRateTasks、fixedDelayTasks),然后注册到ScheduledTaskRegistrar,最后由其激活Task。

3、激活Task

registrar.afterPropertiesSet();

public class ScheduledTaskRegistrar implements InitializingBean, DisposableBean {
    
    public void afterPropertiesSet() {
    	scheduleTasks();
    }
    
    /**
     * Schedule all registered tasks against the underlying task scheduler.
     */
    protected void scheduleTasks() {
        long now = System.currentTimeMillis();
        
        if (this.taskScheduler == null) {
            // Executors 熟悉吧,JDK自带的并发框架来了。
            this.localExecutor = Executors.newSingleThreadScheduledExecutor();
            // Executor包装类,实现不同类型task的分发实现,如下述的CronTask
            this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
        }
        // ...
        if (this.cronTasks != null) {
            // cron 表达式类型的Task处理
        	for (CronTask task : this.cronTasks) {
        	    // 构造ReschedulingRunnable(task, trigger)真正实现task 调度
        		this.scheduledFutures.add(this.taskScheduler.schedule(task.getRunnable(), task.getTrigger()));
        	}
        }
        // ...
    }
}// ReschedulingRunnable见名知义,reuse-schedule
class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture {
    // ...
    public ScheduledFuture schedule() {
        synchronized (this.triggerContextMonitor) {
            // 1.根据CronTrigger,计算表达式得出下一次的执行时间
            this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
            // 2.calculate the time from now to delay execution
            long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
            // 3.调度Task
            this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
            return this;
        }
    }
    // ...
}

    
    
4、finally,调度任务就乖乖的定时execute啦。



附ScheduledExecutorService自带Example:

// ScheduledExecutorService Usage Example
static class BeeperControl {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public void beepForAnHour() {
        final Runnable beeper = new Runnable() {
            public void run() {
                System.out.println("beep");
            }
        };
        // beep every ten seconds
        final ScheduledFuture
       
        beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 10, TimeUnit.SECONDS);
        // after an hour cancel execution of task
        scheduler.schedule(new Runnable() {
            public void run() {
                beeperHandle.cancel(true);
            }
        }, 60 * 60, TimeUnit.SECONDS);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值