大家好,今天我们将学习如何在 Spring Boot 中使用
@Scheduled注解来调度任务。为了让 Spring Boot 应用程序中的作业定期运行,Spring Boot 提供了
@EnableScheduling和
@Scheduled注解。
将 @EnableScheduling 添加到 Spring Boot 应用程序类
将 @EnableScheduling 注解添加到您的 Spring Boot 应用程序类。@EnableScheduling 是一个 Spring Context 模块注解。它通过 @Import(SchedulingConfiguration.class) 指令在内部导入 SchedulingConfiguration
@SpringBootApplication
@EnableScheduling
public class KnowledgefactoryScheduler {
public static void main(String[] args) {
SpringApplication.run(KnowledgefactoryScheduler.class, args);
}
}
1. 以固定速率安排任务
您可以通过使用 @Scheduled 注释中的 fixedRate 参数来安排方法以固定的时间间隔执行。在下面的示例中,注解的方法将每 3 秒执行一次。
// Scheduling a Task with Fixed Rate
@Scheduled(fixedRate = 3000)
public void scheduleTaskWithFixedRate() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("The Scheduled task with Fixed Rate:" +
sdf.format(cal.getTime()));
}
输出:
The scheduled task with Fixed Rate:22:09:42
The scheduled task with Fixed Rate:22:09:45
The scheduled task with Fixed Rate:22:09:48
The scheduled task with Fixed Rate:22:09:51
2. 以固定延迟安排任务
您可以使用 fixeddelay 参数在上一次调用完成和下一次调用开始之间以固定延迟执行任务。
fixedDelay 参数计算最后一次调用完成后的延迟。
// Scheduling a Task with Fixed Delay
@Scheduled(fixedDelay = 3000)
public void scheduleTaskWithFixedDelay() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("Scheduled task With with Fixed Delay:"
+ sdf.format(cal.getTime()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
}
由于任务本身需要 5 秒才能完成,并且我们已指定在上一次调用完成和下一次调用开始之间有 3 秒的延迟,因此每次调用之间会有 8 秒的延迟 -
输出:
Scheduled task With with Fixed Delay:22:16: 54
Scheduled task With with Fixed Delay:22:17: 02
Scheduled task With with Fixed Delay:22:17: 10
3. 以固定速率和初始延迟调度任务
您可以将 initialDelay 参数与 fixedRate 和 fixedDelay 一起使用,以指定的毫秒数延迟任务的第一次执行。
在下面的例子中,任务的第一次执行会延迟5秒,然后以3秒的固定间隔正常执行——
// Scheduling a Task With Fixed Rate and Initial Delay
@Scheduled(fixedRate = 3000, initialDelay = 6000)
public void scheduleTaskWithInitialDelay() {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println("Scheduled task With Fixed Rate
and Initial Delay:" + sdf.format(cal.getTime()));
}
4. 使用 Cron 表达式调度任务
如果上述简单参数不能满足您的需求,那么您可以使用 cron 表达式来安排任务的执行。
让我们看一些使用字段和特殊字符组合的 cron 表达式示例:
每个圣诞节的午夜
// Scheduling a Task using Cron Expression: every Christmas Day at midnight
@Scheduled(cron = "0 0 0 25 12 ?")
public void scheduleTaskWithCronExpression() {
System.out.println("Scheduled Task using Cron
Expression:every Christmas Day at midnight");
}
一个 Cron 表达式由六个连续的字段组成 -
second, minute, hour, day of month, month, day(s) of week
并声明如下
@Scheduled(cron = "* * * * * *")
我们还可以将时区设置为 -
@Scheduled(cron="* * * * * *", zone="Europe/Istanbul")
注释: -
syntax means example explanation
------------------------------------------------------------------------------------
* match any "* * * * * *" do always
*/x every x "*/5 * * * * *" do every five seconds
? no specification "0 0 0 25 12 ?" do every Christmas Day
例子: -
syntax means
------------------------------------------------------------------------------------
"0 0 * * * *" the top of every hour of every day.
"*/10 * * * * *" every ten seconds.
"0 0 8-10 * * *" 8, 9 and 10 o'clock of every day.
"0 0/30 8-10 * * *" 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.
"0 0 9-17 * * MON-FRI" on the hour nine-to-five weekdays
"0 0 0 25 12 ?" every Christmas Day at midnight
@Scheduled()
对于每个匹配的情况,都会显式调用使用声明的方法。
如果我们希望在遇到 cron 表达式时执行某些代码,那么我们必须在注解中指定它:
@Component
public class MyScheduler{
@Scheduled(cron="*/5 * * * * MON-FRI")
public void doSomething() {
// this will execute on weekdays
}
}
如果我们想每隔 5 秒在控制台中打印一次当前时间 -
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 Scheduler {
private static final Logger log = LoggerFactory.getLogger(Scheduler.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(cron = "*/5 * * * * *")
public void currentTime() {
log.info("Current Time = {}", dateFormat.format(new Date()));
}
}
使用 XML 配置的示例:
示例类:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component("schedulerBean")
public class Scheduler {
private static final Logger log = LoggerFactory.getLogger(Scheduler.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
public void currentTime() {
log.info("Current Time = {}", dateFormat.format(new Date()));
}
}
示例 XML(task-context.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-4.1.xsd">
<task:scheduled-tasks scheduler="scheduledTasks">
<task:scheduled ref="schedulerBean" method="currentTime" cron="*/5 * * * * MON-FRI" />
</task:scheduled-tasks>
<task:scheduler id="scheduledTasks" />
</beans>