spring boot 整合 scheduled 实现定时任务
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
启用定时任务的注解
定时任务的启动需要添加注解 @EnableScheduling 来启用,如果不添加这个注解则无法启动,添加的位置不固定
@SpringBootApplication
@EnableScheduling
public class ScheduledApplication {
public static void main(String[] args) {
SpringApplication.run(ScheduledApplication.class, args);
}
}
定义定时任务
在项目中如果启用的定时任务的配置后,需要在要启动的定时任务的方法上添加注解 @Scheduled 标识定时任务,该注解可以使用在注解和方法上,不能使用在类上。
@Scheduled注解定义了三种策略是实现延时任务的方式。部分源码如下:
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String cron() default "";
long fixedDelay() default -1;
long fixedRate() default -1;
long initialDelay() default -1;
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}
通过@Scheduled注解可知,定时任务时间设置可以通过三种策略设置:fixedRate,fixedDelay,cron
三种方式,其中cron方式设置定时任务比较灵活。
- fixedRate 适用于需要严格维持任务执行速率、即使前一个任务未结束也应启动下一个任务的场景,但可能引发并发问题。
- fixedDelay 适用于不希望任务之间相互干扰、需要等待前一个任务完全结束再开始下一个任务的场景,避免了并发问题。
- cron 适用于需要按照复杂、非固定间隔执行任务的场景,提供高度的定时策略定制能力
public class ScheduledTask {
@Scheduled(cron = "* 0/10 * * * ? ")
public void fiveSecondPrint() {
try {
log.info("cron每十分钟执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(10));
} catch (Exception e) {
}
}
@Scheduled(initialDelay = 1, fixedRate = 1, timeUnit = TimeUnit.HOURS)
public void fixedRate() {
try {
log.info("fixedRate每一小时执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(100));
} catch (Exception e) {
}
}
@Scheduled(initialDelay = 1, fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
public void fixedDelay() {
try {
log.info("fixedDelay执行一次任务:{}-{}", LocalTime.now(), new Random().nextInt(100));
} catch (Exception e) {
}
}
}
定时任务相关配置
定时任务执行使用的异步的方式进行,默认的线程池大小为1,但是可以根据实际情况进行配置实现,扩展线程池容量,线程池名称以及其他配置,实现方式有两种方式分别为:
配置文件实现日志相关配置
spring:
task:
scheduling:
pool:
size: 5
thread-name-prefix: custom-scheduling-
shutdown:
await-termination: true
配置类实现定时任务线程池配置
public class CustomerScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(scheduledExecutor());
}
@Bean
public ThreadPoolTaskScheduler scheduledExecutor() {
ThreadPoolTaskScheduler taskExecutor = new ThreadPoolTaskScheduler();
taskExecutor.setPoolSize(2);
taskExecutor.setThreadNamePrefix("custom-schedule-");
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.initialize();
return taskExecutor;
}
}
通过以上两种方式都可以实现对定时任务线程池进行自定义配置,比较推荐使用配置类的方式进行自定义定时任务的配置,可以进行自定义的配置项有很多,更加方便扩展更多的配置项,而配置类可以进行自定义配置的选项较少。