基于Spring Task的Spring定时任务
1 使用@Scheduled注解
举例:
/** * @desc: 基于注解的Spring定时任务 * @author: YanMingXin * @create: 2021/9/28-16:25 **/ @Configuration @EnableScheduling public class SpringScheduleTask { /** * cron方式 */ @Scheduled(cron = "*/5 * * * * ?") private void configureTasks1() { System.err.println("定时任务1......"); } /** * fixedRate方式 */ @Scheduled(fixedRate = 1) private void configureTasks2() { System.out.println("定时任务2......"); } } 复制代码
注意:fixedRate和cron不可以同时使用
1.1 cron方式
字段含义:
- *:代表全部可能的值
- -:指定范围例如1-4
- ,:表示或 例如在分钟里,"5,15"表示5分钟和20分钟触发
- W:只能用在月份中,表示最接近指定天的工作日
- #:用在星期中表示这个月的第几个周几,例如5#3表示这个月的第3个周五
- /:表示增量 例如在分钟里,"3/15"表示从3分钟开始,没隔15分钟执行一次
- ?:表示没有具体的值
- L:表示last,在星期中表示周日,月份中表示最后一天,6L表示这个月倒数第6天,FRIL表示这个月的最后一个星期五
网络异常,图片无法展示
|
示例:
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 * * * * ? 每1分钟触发一次
0 0 * * * ? 每天每1小时触发一次
0 0 10 * * ? 每天10点触发一次
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
1.2 fixedRate方式
配合timeUnit参数,例如
@Scheduled(fixedRate = 1,timeUnit = TimeUnit.SECONDS) private void configureTasks2() { System.out.println("定时任务2......"); } 复制代码
TimeUnit的枚举类型主要有
- DAYS :天
- HOURS :小时
- MINUTES :分钟
- SECONDS :秒钟
- MILLISECONDS :毫秒
- MICROSECONDS :微秒
- NANOSECONDS:纳秒
1.3 @Scheduled注解源码
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable(Schedules.class) public @interface Scheduled { String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED; String cron() default ""; //配置cron参数 String zone() default ""; //配置时区 long fixedDelay() default -1; String fixedDelayString() default ""; long fixedRate() default -1; String fixedRateString() default ""; long initialDelay() default -1; String initialDelayString() default ""; // TimeUnit timeUnit() default TimeUnit.MILLISECONDS; //配置时间单位,默认毫秒 } 复制代码
2 实现SchedulingConfigurer接口
2.1 代码实现
/** * @desc: 实现SchedulingConfigurer接口来实现定时任务 * @author: YanMingXin * @create: 2021/9/28-17:12 **/ @Configuration @EnableScheduling public class SpringScheduleTaskImpl implements SchedulingConfigurer { /** * 实现自定义任务 * * @param taskRegistrar */ @SuppressWarnings("all") @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(() -> { System.out.println("定时任务3......"); }, triggerContext -> { return new CronTrigger("0/1 * * * * ?").nextExecutionTime(triggerContext); }); taskRegistrar.addFixedRateTask(() -> { System.out.println("定时任务4......"); }, 1000 ); taskRegistrar.addCronTask(() -> { System.out.println("定时任务5......"); }, "0/1 * * * * ?" ); } } 复制代码
2.2 配置文件方式
配置文件:
server.port=0 task.cron=0/2 * * * * ? 复制代码
代码:
/** * @desc: 实现SchedulingConfigurer接口来实现定时任务 * @author: YanMingXin * @create: 2021/9/28-17:12 **/ @Configuration @EnableScheduling public class SpringScheduleTaskImplByFile implements SchedulingConfigurer { @Value("${task.cron}") private String cron; /** * 实现自定义任务 * * @param taskRegistrar */ @SuppressWarnings("all") @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(() -> { System.out.println("定时任务7......"); }, triggerContext -> { return new CronTrigger(cron).nextExecutionTime(triggerContext); }); } } 复制代码
2.3 数据库方式
/** * @desc: * @author: YanMingXin * @create: 2021/9/28-17:44 **/ @Configuration @EnableScheduling public class SpringScheduleTaskImplByDB implements SchedulingConfigurer { @TableName("tb_task") @Data class MyTask { @TableId(type = IdType.AUTO,value = "id") private Integer id; @TableField(value = "cron") private String cron; } @Mapper interface TaskMapper extends BaseMapper<MyTask> { } @Autowired private TaskMapper taskMapper; /** * 实现自定义任务 * * @param taskRegistrar */ @SuppressWarnings("all") @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(() -> { System.out.println("定时任务10......"); }, triggerContext -> { MyTask myTask = taskMapper.selectById(1); return new CronTrigger(myTask.getCron()).nextExecutionTime(triggerContext); }); } } ..."); }, triggerContext -> { MyTask myTask = taskMapper.selectById(1); return new CronTrigger(myTask.getCron()).nextExecutionTime(triggerContext); }); } } 复制代码
3 对比
基于注解形式的一般都是静态的定时任务,就是注解中的内容是固定的并且只有一个定时任务,而实现接口的可以是动态的,可以根据配置文件和数据库进行切换。