Spring Boot系列三 Spring @EnableScheduling 定时任务用法总结
2017-04-06 19:46
1006 查看
1. 原理
1.1 TaskScheduler
TaskScheduler是spring的定时任务使用的线程池的关键类public interface TaskScheduler { // 通过Trigger执行任务 ScheduledFuture schedule(Runnable task, Trigger trigger); // 指定时间执行任务 ScheduledFuture schedule(Runnable task, Date startTime); // 指定在指定时间后,循环周期执行任务 ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); // 循环周期执行任务 ScheduledFuture scheduleAtFixedRate(Runnable task, long period); // 延迟N时间,在指定日期执行 ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay); }
TaskScheduler有两种实现方式:
- TimerManagerTaskScheduler:使用外部对象管理线程池,如 CommonJ TimerManager,适用于多个进程共享线程池
- ThreadPoolTaskScheduler: 如果仅仅在同一进程管理线程池,则推荐使用此对象。它实际使用Java自我的ScheduledExecutorService管理线程池
1.2 Trigger
Trigger是定时任务配置的关键类,配置方法的下次执行时间public interface Trigger { Date nextExecutionTime(TriggerContext triggerContext); }
方法里的参数TriggerContext是封装了任务最后执行的时间和最后执行完毕的时间
public interface TriggerContext { Date lastScheduledExecutionTime(); Date lastActualExecutionTime(); Date lastCompletionTime(); }
TriggerContext默认的实现是SimpleTriggerContext,看源码实现非常简单
Trigger的实现类:
- CronTrigger:使用cron表达式定义任务执行时机
如:
scheduler.schedule(task, new CronTrigger("0 15 9-17 * * MON-FRI"));
- PeriodicTrigger:通过“fixed period,”,“initial delay value”,“boolean to indicate whether the period should be interpreted as a fixed-rate or a fixed-delay”3个参数配置任务执行的时机
2. 定时方法@Scheduled
通过@Scheduled定义定时任务fixedDelay: 每次方法执行完毕后,等待Nms再执行此方法。
/** * 每次方法执行完毕后,等待5s再执行此方法。 * 同时只能有个线程运行此方法 */ @Scheduled(fixedDelay=5000) public void fixedDelay() { try { // 执行方法需要10s Thread.sleep(1000 * 10); } catch (InterruptedException e) { } log.info("fixedDelay--"); }
注意:定时方法返回值只能是void且不能有传入参数
fixedRate: 每隔5s调用一次此方法,无论之前的方法是否执行完毕
/** * 每隔5s调用一次此方法,无论之前的方法是否执行完毕 * 同时可能有N个线程执行此方法 * */ @Scheduled(fixedRate=5000) public void fixedRate() { try { // 执行方法需要10s Thread.sleep(1000 * 10); } catch (InterruptedException e) { } log.info("fixedRate--"); }
initialDelay: 第一次调用此方法前的等待时间
/*** * initialDelay: 第一次调用此方法前的等待时间 * */ @Scheduled(initialDelay=1000, fixedRate=5000) public void initialDelayAndfixedRate() { log.info("initialDelayAndfixedRate--"); }
cron:通过cron配置值
/** * 支持cron语法: * 每个参数的意义分别是: second, minute, hour, day of month, month, day of week * * 如下:周一至周五,每隔5s执行一次方法 */ @Scheduled(cron="*/5 * * * * SUN-MON") public void cron() { log.info("cron--"); }
完整的demo代码
/**
* 定时类
* 不同异步方法:定时方法只能返回void且不能接受任务参数
*
* @author hry
*
*/
@Component
public class ScheduleDemo {
private static final Logger log = Logger.getLogger(ScheduleDemo.class);
/**
* 每次方法执行完毕后,等待5s再执行此方法。
* 同时只能有个线程运行此方法
*/
@Scheduled(fixedDelay=5000)
public void fixedDelay() {
try {
// 执行方法需要10s
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
}
log.info("fixedDelay--");
}
/** * 每隔5s调用一次此方法,无论之前的方法是否执行完毕 * 同时可能有N个线程执行此方法 * */ @Scheduled(fixedRate=5000) public void fixedRate() { try { // 执行方法需要10s Thread.sleep(1000 * 10); } catch (InterruptedException e) { } log.info("fixedRate--"); }
/*** * initialDelay: 第一次调用此方法前的等待时间 * */ @Scheduled(initialDelay=1000, fixedRate=5000) public void initialDelayAndfixedRate() { log.info("initialDelayAndfixedRate--"); }
/**
* 支持cron语法:
* 每个参数的意义分别是: second, minute, hour, day of month, month, day of week
*
* 如下:周一至周五,每隔5s执行一次方法
*/
@Scheduled(cron="*/5 * * * * SUN-MON")
public void cron() {
log.info("cron--");
}
}
3. 定时方法启动方式
启动定时任务有以下方式1. 注解
通过@EnableScheduling启动定时任务
``` @SpringBootApplication @EnableScheduling // 启动定时任务 public class ScheduleApplicationWithAnnotation { private static final Logger log = LoggerFactory.getLogger(ScheduleApplicationWithAnnotation.class); /** * 自定义定时任务线程池 * 如果没有,则使用默认定时任务池 * @return */ @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return new ScheduledThreadPoolExecutor(10, new ThreadFactory() { private AtomicInteger max = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { return new Thread(r, "mySchedulAnno-" + max.incrementAndGet()); } }); } public static void main(String[] args) { log.info("Start ScheduleApplicationWithAnnotation.. "); SpringApplication.run(ScheduleApplicationWithAnnotation.class, args); } } ```
2. XML配置
task:annotation-driven等价于@EnableScheduling,启动定时任务
task:annotation-driven等价于 @EnableScheduling, scheduler指定线程池
id指定线程池产生线程名称的前缀
<task:annotation-driven scheduler="myScheduler"/> <task:scheduler id="myScheduler" pool-size="10" />
``` /** * 通过XML启动异步方法 * @author hry * */ @SpringBootApplication @ImportResource("classpath:/schedule/spring_schedule.xml") public class ScheduleApplicationWithXML { private static final Logger log = LoggerFactory.getLogger(ScheduleApplicationWithXML.class); public static void main(String[] args) { log.info("Start ScheduleApplicationWithXML.. "); SpringApplication.run(ScheduleApplicationWithXML.class, args); } } ```
4. 自定义配置线程池
通过实现SchedulingConfigurer 对定时任务线程池进行更细化的配置 ``` /** * 通过实现SchedulingConfigurer对定时任务线程池进行更细致配置 * @author hry * */ @Component @Configuration public class MySchedulingConfigurer implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.setScheduler(taskExecutor()); } @Bean(destroyMethod="shutdown") public Executor taskExecutor() { return new ScheduledThreadPoolExecutor(10, new ThreadFactory() { private AtomicInteger max = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { return new Thread(r, "myScheConfig-" + max.incrementAndGet()); } }); } } ``` 通过@EnableScheduling启动定时方法 ``` /** * 通过@EnableScheduling启动定时方法 * 配置 * * @author hry * */ @SpringBootApplication @EnableScheduling // 启动定时任务 public class ScheduleApplicationWithSchedulingConfigurer { private static final Logger log = LoggerFactory.getLogger(ScheduleApplicationWithSchedulingConfigurer.class); public static void main(String[] args) { log.info("Start ScheduleApplicationWithSchedulingConfigurer.. "); SpringApplication.run(ScheduleApplicationWithSchedulingConfigurer.class, args); } } ```
5. 代码
github相关文章推荐
- spring boot 计划任务,定时任务的注解的使用@Scheduled@EnableScheduling
- Redis系列三 - Spring boot如何使用redis做缓存及缓存注解的用法总结
- SpringBoot入门系列篇(四):使用SpringBoot创建定时任务
- Redis系列三 - Spring boot如何使用redis做缓存及缓存注解的用法总结
- SpringBoot非官方教程 | 第十八篇: 定时任务(Scheduling Tasks)
- Spring Boot系列二 Spring @Async异步线程池用法总结
- SpringBoot非官方教程 | 第十八篇: 定时任务(Scheduling Tasks)
- SpringBoot非官方教程 | 第十八篇: 定时任务(Scheduling Tasks)
- Spring Boot 与 Kotlin 定时任务(Scheduling Tasks)
- spring boot @EnableScheduling 没开启依然启动了定时器任务
- spring boot: @EnableScheduling开启计划任务支持,@Scheduled计划任务声明
- spring boot-高级话题之 多线程、@EnableScheduling开启计划任务的支持(2)
- spring boot: 计划任务@ EnableScheduling和@Scheduled
- springboot系列 | 定时任务
- SpringBoot 开启关闭自动任务配置(EnableScheduling )
- Redis系列三 - Spring boot如何使用redis做缓存及缓存注解的用法总结
- Redis系列四 - 在springboot中通过Lua脚本在redis中实现定时任务
- 关于Spring定时任务(定时器)用法
- springboot 添加job定时任务
- Spring Boot定时任务的使用方法