文章目錄
- Spring Task 定時任務
- pom 包配置
- 啟動類開啟定時
- 創建定時任務實現類
- 定時任務 1:
- 定時任務 2:
- 參數說明
- fixedRate 說明
- cron 說明
- 并行任務
Spring Task 定時任務
在項目開發中,經常需要定時任務來幫助我們來做一些內容,比如定時派息、跑批對賬、業務監控等。
實現定時任務有 3 種方式:
-
java 自帶的 API:java.util.Timer 類和 java.util.TimerTask 類;
-
Quartz 框架:開源 功能強大 使用起來稍顯復雜;
-
Spring 3.0 以后自帶了 task 調度工具,也稱 Spring Task,它比 Quartz 更加的簡單方便。
pom 包配置
pom 包里面只需要引入 SpringBoot Starter 包即可,SpringBoot Starter 包中已經內置了定時的方法。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
啟動類開啟定時
在啟動類上面加上 @EnableScheduling 即可開啟定時:
@SpringBootApplication
@EnableScheduling
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
創建定時任務實現類
使用 SpringBoot 自帶的定時非常的簡單,只需要在方法上面添加 @Scheduled 注解即可。
定時任務 1:
@Component
public class SchedulerTask {private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);private int count = 0;@Scheduled(cron="*/6 * * * * ?")private void process() {log.info("{}", "this is scheduler task running " + (count++));}
}
設置 process()
每隔六秒執行一次,并統計執行的次數。
我們還有另外的一種方案來設置,固定時間周期執行方法。
定時任務 2:
@Component
public class Scheduler2Task {private static final Logger log = LoggerFactory.getLogger(Scheduler2Task.class);private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");@Scheduled(fixedRate = 6000)public void reportCurrentTime() {log.info("{}", "現在時間:" + dateFormat.format(new Date()));}
}
啟動項目之后,就會在控制臺看到打印的結果。
結果如下:
INFO [ scheduling-1] com.example.timingtask.Scheduler2Task : 現在時間:20:12:02
INFO [ scheduling-1] com.example.timingtask.SchedulerTask : this is scheduler task running 0
INFO [ scheduling-1] com.example.timingtask.Scheduler2Task : 現在時間:20:12:08
INFO [ scheduling-1] com.example.timingtask.SchedulerTask : this is scheduler task running 1
INFO [ scheduling-1] com.example.timingtask.Scheduler2Task : 現在時間:20:12:14
INFO [ scheduling-1] com.example.timingtask.SchedulerTask : this is scheduler task running 2
說明兩個方法都按照固定 6 秒的頻率來執行。
參數說明
@Scheduled 參數可以接受兩種定時的設置,一種是我們常用的 cron="*/6 * * * * ?"
,一種是 fixedRate = 6000
,兩種都可表示固定周期執行定時任務。
fixedRate 說明
- @Scheduled(fixedRate = 6000) : 上一次開始執行時間點之后 6 秒再執行。
- @Scheduled(fixedDelay = 6000) : 上一次執行完畢時間點之后 6 秒再執行。
- @Scheduled(initialDelay=1000, fixedRate=6000) : 第一次延遲 1 秒后執行,之后按 fixedRate 的規則每 6 秒執行一次。
cron 說明
用來配置定時任務的時間表達式,通常用于在Unix/Linux系統中設置定時任務。
在Java應用程序中,Cron表達式也被廣泛使用,比如在Quartz調度框架中用來配置定時任務的觸發時間。Cron表達式由7個字段組成,分別表示秒、分鐘、小時、日期、月份、星期和年(可選)。
每個字段可以包含多個取值,以逗號分隔,或者可以使用通配符和范圍來表示時間。以下是Cron表達式的基本格式:plaintext
秒 分 時 日 月 星期 年
其中,各字段的取值范圍如下:秒(0-59)、分鐘(0-59)、小時(0-23)、日期(1-31)、月份(1-12或者 JAN-DEC)
星期(0-7或者 SUN-SAT,0和7都代表星期日)、年(可選,留空表示每年)。以下是一些常見的Cron表達式示例:
0 0 12 * * ?:每天中午12點觸發
0 0/5 * * * ?:每隔5分鐘觸發
0 0 8-10 * * ?:每天上午8點至10點之間每小時觸發
0 0 6,18 * * ?:每天早上6點和晚上6點觸發
0 0 9 ? * MON-FRI:周一至周五的早上9點觸發
并行任務
了解
之前的的定時任務都是串行執行的。所謂串行執行指的是只由一個線程來執行任務。除了這種方式 Spring Task 還支持并行執行任務,即由多個線程來執行不同的任務。
要實現這樣的功能,你需要去進行額外的配置:
@Configuration
@EnableScheduling
public class TimingTaskConfig implements SchedulingConfigurer, AsyncConfigurer {// 線程池線程數量private static final int corePoolSize = 5;@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.initialize(); // 初始化線程池scheduler.setPoolSize(corePoolSize); // 線程池容量return scheduler;}@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setTaskScheduler(taskScheduler());}@Overridepublic Executor getAsyncExecutor() {return taskScheduler();}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return null;}
}
注意,這時 @EnableScheduling
注解標注在了這個配置類上,因此,Spring Boot 的入口類上就不再需要標注它了。(當然,你硬要把它標注在入口類上其實也可以)。
其它的相關代碼無需修改,運行項目你會看到類似如下的日志輸出:
INFO [taskScheduler-1] com.example.timingtask.Scheduler2Task : 現在時間:20:08:57
INFO [taskScheduler-1] com.example.timingtask.SchedulerTask : this is scheduler task running 0
INFO [taskScheduler-2] com.example.timingtask.Scheduler2Task : 現在時間:20:09:03
INFO [taskScheduler-3] com.example.timingtask.SchedulerTask : this is scheduler task running 1
INFO [taskScheduler-1] com.example.timingtask.Scheduler2Task : 現在時間:20:09:09
INFO [taskScheduler-4] com.example.timingtask.SchedulerTask : this is scheduler task running 2