在后端開發中,有些場景是需要使用定時任務的,例如:定時同步一批數據、定時清理一些數據,在Spring Boot中提供了@Scheduled
注解就提供了定時調度的功能,對於簡單的、單機的調度方案是足夠了的。這篇文章准備用實際案例看下@Scheduled
的用法。
開發實戰
-
新建Spring Boot工程,主pom文件內容如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>online.javaadu.schedule</groupId> <artifactId>scheduledemo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>scheduledemo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
-
新建定時任務組件,使用
@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 { /** * 特殊的cron表達式,如果設置成這個值,則表示將定時調度器關閉,不再調度。 */ String CRON_DISABLED = ScheduledTaskRegistrar.CRON_DISABLED; /** * cron表達式,可以支持復雜的定時調度需求 */ String cron() default ""; /** * cron表達式解析的時候,解析依賴的時區 */ String zone() default ""; /** * 兩次調度觸發之間暫停的毫秒數,Long類型 */ long fixedDelay() default -1; /** * 兩次調度觸發之間暫停的毫秒數,String類型 */ String fixedDelayString() default ""; /** * 每隔幾毫秒調度一次 */ long fixedRate() default -1; /** * 每隔幾毫秒調度一次,String類型 */ String fixedRateString() default ""; /** * 第一次執行之前,延遲多少毫秒 */ long initialDelay() default -1; /** * 第一次執行之前,延遲多少毫秒,String類型 */ String initialDelayString() default ""; }
來源:吉林網站優化