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);
});
}
}
3 对比
基于注解形式的一般都是静态的定时任务,就是注解中的内容是固定的并且只有一个定时任务,而实现接口的可以是动态的,可以根据配置文件和数据库进行切换。