本文首发于个人网站:Spring Boot 2.x实战之定时任务调度
在后端开发中,有些场景是需要使用定时任务的,例如:定时同步一批数据、定时清理一些数据,在Spring Boot中提供了@Scheduled注解就提供了定时调度的功能,对于简单的、单机的调度方案是足够了的。这篇文章准备用实际案例看下@Scheduled的用法。
开发实战-
新建Spring Boot工程,主pom文件内容如下:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE online.javaadu.schedule scheduledemo 0.0.1-SNAPSHOT scheduledemo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-maven-plugin -
新建定时任务组件,使用@Scheduled注解修饰要调度的方法,在该方法中会打印当前的时间。
package online.javaadu.schedule.scheduledemo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Component public class ScheduledTasks { private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); //第一次执行之前延后10秒钟;后续每隔5秒执行1次 @Scheduled(fixedRate = 5000, initialDelay = 10000) public void reportCurrentTime() { log.info("The time is now {}", dateFormat.format(new Date())); } } -
在ScheduledemoApplication中开启定时调度能力——即开启@Scheduled注解的定时调度功能,并在系统刚起来的时候打印一行日志,用来体现上一步中的initialDelay的作用。
package online.javaadu.schedule.scheduledemo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; import java.text.SimpleDateFormat; import java.util.Date; @SpringBootApplication @EnableScheduling public class ScheduledemoApplication { private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); public static void main(String[] args) { SpringApplication.run(ScheduledemoApplication.class, args); log.info("---The time is now {}", dateFormat.format(new Date())); } } -
点击运行后,该demo的运行结果如下,可以看出,23:15:35应用启动,过了10秒钟定时调度任务才开始执行,然后是每隔5秒钟打印一次时间。
我们一起来看下@Scheduled注解的源码,看看除了上面的例子里提供的案例,该注解还有哪些功能呢?
- cron,可以支持更复杂的时间复杂度
- zone,解析cron表达式的时候解析时区
- fixedDelay(和fixedDelayString),两次调度之间需要加一个固定的延迟
- fixedRate(和fixedRateString),没隔多久需要调度一次
- initialDelay(和initialDelayString),第一次调度之前需要延迟多久
@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 "";
String zone() default "";
long fixedDelay() default -1;
String fixedDelayString() default "";
long fixedRate() default -1;
String fixedRateString() default "";
long initialDelay() default -1;
String initialDelayString() default "";
}
参考资料
- https://spring.io/guides/gs/scheduling-tasks/
- 《Spring Boot实战》
- Spring Boot 2.x实战之StateMachine
本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。



