四、springBoot 優雅的創建定時任務

四、springBoot 優雅的創建定時任務

前言

好幾天沒寫了,工作有點忙,最近工作剛好做一個定時任務統計的,所以就將springboot 如何創建定時任務整理了一下。總的來說,springboot創建定時任務是非常簡單的,不用像spring 或者springmvc 需要在xml 文件中配置,在項目啟動的時候加載。spring boot 使用註解的方式就可以完全支持定時任務。不過基礎註解的話,可能有的需求定時任務的時間會經常變動,註解就不好修改,每次都得重新編譯,所以想將定時時間存在數據庫,然後項目讀取數據庫執行定時任務,所以就有了基於接口的定時任務。下面就分基於註解和基於接口詳細講解。

基於註解

pom.xml 文件不用修改,我們原本的項目就支持,其實定時器是springboot框架自帶的,不用引入什麼依賴。我們直接創建一個autotask 包,創建一個AutoTask類。

@EnableScheduling
@Component
@Slf4j
public class AutoTask {
@Scheduled(cron="*/6 * * * * ?")
private void process(){
log.info("autoTask ");
}
}

這樣一個定時器就創建啦,在項目啟動後,會每隔6s 打印“autoTask”的日誌。是不是很簡單。主要用到的兩個註解就是@EnableScheduling 和 @Scheduled。註解@EnableScheduling 就是開啟定時任務的。哪個類的中的方法想要定期執行,就在這個類上加入這個註解。當然這個這個註解也可以加在啟動類上。加在啟動類上表示項目中所有的類都可以創建定時任務。

四、springBoot 優雅的創建定時任務

@Scheduled 註解就是我們常見的定時器啦,後面的cron 就是定時任務表達式。在方法上註解,表示這個方法定期執行。

四、springBoot 優雅的創建定時任務

不過@Scheduled 可以進行兩種配置,我們熟悉的cron ,還有一種是fixedRate。比如fixedRate=6000 表示方法每6秒鐘執行一次。我們來啟動項目看一下,可以看到兩個方法都在定期執行。

四、springBoot 優雅的創建定時任務

基於接口

上面可以看到springboot 基於註解是非常方便的。但是對於頻繁變動或者一個項目中有很多的定時器那就不方便管理了。所以統一將定時器信息存放在數據庫中。


DROP TABLE IF EXISTS `scheduled`;
CREATE TABLE `scheduled` (
`cron_id` varchar(30) NOT NULL PRIMARY KEY,
`cron_name` varchar(30) NULL,
`cron` varchar(30) NOT NULL
);
INSERT INTO `scheduled` VALUES ('1','定時器任務一','0/6 * * * * ?');
四、springBoot 優雅的創建定時任務

在dao 層mapper1包下創建一個CronMapper接口,很簡單的就獲取cron

public interface CronMapper {
@Select("select cron from scheduled where cron_id = #{id}")
public String getCron(int id);
}
四、springBoot 優雅的創建定時任務

這裡我們就不寫service 層了。直接在autotask 包下創建一個AutoTaskFromDB類

@Slf4j
@Component
public class AutoTaskFromDB implements SchedulingConfigurer {
@Autowired
protected CronMapper cronMapper;

@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addTriggerTask(() -> process(),
triggerContext -> {
String cron = cronMapper.getCron(1);
if (cron.isEmpty()) {
log.info("cron 為空");
}
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
private void process(){
log.info("formDB ");
}
}

可以看到也很簡單,就是實現SchedulingConfigurer 這個吧接口,addTriggerTask()是添加一個定時器。process()方法是我們需要定時執行的方法體。CronTrigger(cron).nextExecutionTime(triggerContext) 就是從數據庫讀取的cron 創建定時器。

這個類我沒有加上@EnableScheduling 註解,因為我在啟動類上加上了,如果你們啟動類上沒有加,這裡記得加上。

測試一下;下圖可以看到三個定時任務都執行了,fromDB 是從數據庫讀取的。

四、springBoot 優雅的創建定時任務

cron

cron 用法網上有很多,也沒有什麼講的這裡就附帶記錄下

結構

cron表達式是一個字符串,分為6或7個域,每兩個域之間用空格分隔,其語法格式為:"秒域 分域 時域 日域 月域 周域 年域"

取值範圍

域名 可取值 可取符號(僅列部分常用) 秒域 0~59的整數 * - , / 分域 0~59的整數 * - , / 時域

0~23的整數 * - , / 日域

1~31的整數 * - , / ? L 月域

1~12的整數或JAN~DEC * - , / 周域

1~7的整數或SUN~SAT * - , / ? L # 年域

1970~2099的整數

* - , / 常例

番外

本來這個知識點不應該放在這裡講的,但是不多,順帶寫了,剛好也能做定時器。我們項目中往往有一些需求需要在項目啟動的時候就執行,那這個我們怎麼實現了。其實spring boot 使用起來也非常簡單,只用實現 ApplicationRunner 就好了。我們在autotask 包下創建一個AutoTaskFromSpringRunner類

@Slf4j
@Component
public class AutoTaskFromSpringRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
process();
}
private void process(){
log.info(" run ApplicationArguments");
}
}

啟動項目看一下,可以發現這個會在項目啟動後執行,但是隻會執行一次。

四、springBoot 優雅的創建定時任務

那這個怎麼用來做定時器呢?當然是結合線程來做啦,但是這個方法其實不建議,b畢竟線程很容易出問題,但是提供一種思路:

@Slf4j
@Component
public class AutoTaskFromSpringRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
process();
new Thread(() -> {
while (true) {
process2();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
log.error("{}",e);
}
}
}).start();
}
private void process(){
log.info(" run ApplicationArguments");
}
private void process2(){
log.info("線程定時器");
}
}

啟動項目看下,發現也是可以起到定時器的作用的。

四、springBoot 優雅的創建定時任務

好了,就說這麼多啦,今天項目的代碼也同步到github 上啦。github地址:https://github.com/QuellanAn/zlflovemm

後續加油♡

歡迎大家關注個人公眾號 "程序員愛酸奶"

分享各種學習資料,包含java,linux,大數據等。資料包含視頻文檔以及源碼,同時分享本人及投遞的優質技術博文。

如果大家喜歡記得關注和分享喲❤

四、springBoot 優雅的創建定時任務


分享到:


相關文章: