一、前言
這篇是學習SpringBoot的第六篇文章,這篇記錄的是SpringBoot內置的定時任務的使用。這邊文章的程序是沿用上一篇的。如果不想從頭配置,可以先創建一個SpringBoot的工程,然後再使用這篇文章的代碼,MybatisPlus部分的也就是getUser方法需要替換掉。
Task在Spring應用中,使用比較簡單,直接使用@Scheduled註解即可,但是不能夠動態維護,任務啓動以後不能修改、暫停等。
二、直接上代碼
2.1在啓動類加上@EnableScheduling註解
package com.xuexue.firstproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class FirstprojectApplication {
public static void main(String[] args) {
SpringApplication.run(FirstprojectApplication.class, args);
}
}
2.2寫一個定時任務吧。這個類要使用@Component註解,將這個類交給Spring管理。如果那個方法需要定時任務,在方法上方加上@Scheduled註解。請注意,任務的方法的返回值應該爲void,並且不能有任何參數。如果需要與應用程序上下文中的其他對象進行交互,那麼通常會通過依賴注入的方式來提供這些對象。
package com.xuexue.firstproject.task;
import com.xuexue.firstproject.Beans.User;
import com.xuexue.firstproject.Daos.UserMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
@Component
public class TaskDemo {
@Resource
private UserMapper userMapper;
@Scheduled(cron = "0 0/1 * * * ?") // 每分鐘執行一次
public void work() throws Exception {
System.out.println("執行調度任務:"+new Date());
}
@Scheduled(fixedRate = 5000)//每5秒執行一次
public void play() throws Exception {
System.out.println("執行Quartz定時器任務:"+new Date());
}
@Scheduled(cron = "0/2 * * * * ?") //每2秒執行一次
public void doSomething() throws Exception {
System.out.println("每2秒執行一個的定時任務:"+new Date());
}
@Scheduled(cron = "0 0 0/1 * * ? ") // 每一小時執行一次
public void goWork() throws Exception {
System.out.println("每一小時執行一次的定時任務:"+new Date());
}
@Scheduled(cron = "0 0/1 * * * ?") // 每分鐘執行一次
public void getUser() throws Exception {
User quartzuser=userMapper.selectById(1);
System.out.println("每分鐘查詢一次用戶:"+quartzuser.getUsername());
}
}
2.3運行結果如下
2.4@Scheduled註解
@Scheduled(fixedRate = 5000):固定間隔5秒,可以引用變量 fixedRate:以每次開始時間作爲測量,間隔固定時間
private static final long SECOND = 1000;
@Scheduled(fixedRate = 3 * SECOND)
public void task1() {}
@Scheduled(fixedDelay = 3000):固定延遲3秒,從前一次任務結束開始計算,延遲3秒執行
@Scheduled(cron = "*/5 * * * * ?"):每5秒執行,使用的是cron表達式運行了
2.5cron表達式
cron表達式是由七個子表達式組成的字符串,用於描述日程表的各個細節。這些子表達式用空格分隔
整體表達式爲:[秒] [分] [小時] [日] [月] [周] [年](年可選)
1.Seconds(秒)
2.Minutes(分)
3.Hours(時)
4.Day-of-Month(日)
5.Month(月)
6.Day-of-Week(星期)
7.Year(可選字段)(年)
下面是每個表達式的取值規則:
字段 | [秒] | [分] | [小時] | [日] | [月] | [周] | [年](年可選) |
允許值 | 0-59 | 0-59 | 0-23 | 1-31 | 1~12 JAN~DEC |
1~7 SUN~SAT |
留空 1970~2099 |
允許特殊符號 | , - * / | , - * / | , - * / | , - * / ? L W C |
, - * / | , - * / ? L C # |
, - * / |
允許值及特殊符號說明:
- 月份簡稱:JAN(一月),FEB(二月),MAR(三月),APR(四月),MAY(五月),JUN(六月),JUL(七月),AUG(八月),SEP(九月),OCT(十月),NOV(十一月)和DEC(十二月)。
- 星期簡稱:SUN(星期日),MON(星期一),TUE(星期二),WED(星期三),THU(星期四),FRI(星期五)和SAT(星期六)。其中,1表示SUN。
- ,:用來分割在域上指定的多個值。如:MON,WED,FRI在星期域裏表示星期一、星期三、星期五。
- /:用於指定增量值。如分鐘上使用0/15,表示從零開始,每隔15分鐘,等價於0,15,30,45。如分鐘上使用3/15,表示從第3分鐘開始,每隔15分鐘,等價於3,18,33,48,x/y中x表示開始值,y表示步長。
- *:表示匹配該域的任意值。如秒上使用*表示每秒觸發一次。
- -:表示指定一個範圍,如分鐘域上10-13,表示10分、11分、12分、13分。
- ?:表示不關心的域,可用於日和周兩個域上,主要用來解決日和周兩個域的衝突。和*類似,區別在於*關心域,只是域的值可以任意,?則表示對該域不關心,不需要看該域的內容,直接忽略。
- L:表示最後,是單詞last的首字母,可用於日和周兩個域上,用在日和週上含義不同:
- 日域上表示月份中日期的最後一天,如一月的第31天、非閏年二月的第28天。
- 周域上單獨使用僅表示7或SAT,即僅表示週六。但是如果跟在其他值後,如6L或FRIL則表示該月中最後一個星期五。
- L還可以指定偏移量,如日域指定L-3,表示該月倒數第3天。當使用L時其值儘量不要指定列表或範圍,以免令人困惑。
- W:用於日域,表示距離指定日最近的工作日(週一至週五中的一個)
例如在日字段上設置"15W",表示離每月15號最近的那個工作日觸發。如果15號正好是週六,則找最近的週五(14號)觸發, 如果15號是周未,則找最近的下週一(16號)觸發。如果15號正好在工作日(週一至週五),則就在該天觸發。如果指定格式爲 "1W",它則表示每月1號往後最近的工作日觸發。如果1號正是週六,則將在3號下週一觸發。(注,"W"前只能設置具體的數字,不允許區間"-")。
小提示:'L'和 'W'可以一組合使用。如果在日字段上設置"LW",則表示在本月的最後一個工作日觸發;周字段的設置,若使用英文字母是不區分大小寫的,即MON與mon相同。 - #:用於周域,表示該月的第n個星期幾。如:周域值爲6#3或FRI#3表示該月的第3個星期五。
例如在周字段上設置"6#3"表示在每月的第三個週六。注意如果指定"#5",正好第五週沒有周六,則不會觸發該配置(用在母親節和父親節再合適不過了)。
注:表中月份一行的JAN-DEC,是指一月到十二月的英文縮寫;星期一行的SUN-SAT,是指星期天到星期六的英文縮寫。
常用表達式:
表達式 | 含義 |
---|---|
0 0 10,14,16 * * ? | 每天上午10點、下午兩點、下午4點整觸發 |
0 0/30 9-17 * * ? | 每天朝九晚五內每隔半小時觸發 |
0 15 10 ? * MON-FRI | 週一至週五的上午10:15觸發 |
0 0/5 * * * ? | 每5分鐘觸發 |
10 0/5 * * * ? | 每隔5分鐘的第10秒觸發(即10:00:10、10:05:10、10:10:10等) |
30 * * * * ? | 每半分鐘觸發 |
30 10 * * * ? | 每小時的10分30秒觸發 |
30 10 1 * * ? | 每天1點10分30秒觸發 |
30 10 1 20 * ? | 每月20號1點10分30秒觸發 |
30 10 1 20 10 ? * | 每年10月20號1點10分30秒觸發 |
30 10 1 20 10 ? 2011 | 2011年10月20號1點10分30秒觸發 |
30 10 1 ? 10 * 2011 | 2011年10月每天1點10分30秒觸發 |
30 10 1 ? 10 SUN 2011 | 2011年10月每週日1點10分30秒觸發 |
15,30,45 * * * * ? | 每15秒,30秒,45秒時觸發 |
15-45 * * * * ? | 15到45秒內,每秒都觸發 |
15/5 * * * * ? | 每分鐘的每15秒開始觸發,每隔5秒觸發一次 |
15-30/5 * * * * ? | 每分鐘的15秒到30秒之間開始觸發,每隔5秒觸發一次 |
0 0/3 * * * ? | 每小時的第0分0秒開始,每三分鐘觸發一次 |
0 15 10 ? * MON-FRI | 星期一到星期五的10點15分0秒觸發 |
0 15 10 L * ? | 每個月最後一天的10點15分0秒觸發 |
0 15 10 LW * ? | 每個月最後一個工作日的10點15分0秒觸發 |
0 15 10 ? * 5L | 每個月最後一個星期四的10點15分0秒觸發 |
0 15 10 ? * 5#3 | 每個月第三週的星期四的10點15分0秒觸發 |