您好,登錄后才能下訂單哦!
springBoot中怎么創建定時任務,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
基于注解
pom.xml 文件不用修改,我們原本的項目就支持,其實定時器是springboot框架自帶的,不用引入什么依賴。我們直接創建一個autotask 包,創建一個AutoTask類。
@EnableScheduling@Component@Slf4jpublic class AutoTask { @Scheduled(cron="*/6 * * * * ?") private void process(){ log.info("autoTask "); }}
這樣一個定時器就創建啦,在項目啟動后,會每隔6s 打印“autoTask”的日志。是不是很簡單。主要用到的兩個注解就是@EnableScheduling 和 @Scheduled。
注解@EnableScheduling 就是開啟定時任務的。哪個類的中的方法想要定期執行,就在這個類上加入這個注解。當然這個這個注解也可以加在啟動類上。加在啟動類上表示項目中所有的類都可以創建定時任務。
@Scheduled 注解就是我們常見的定時器啦,后面的cron 就是定時任務表達式。在方法上注解,表示這個方法定期執行。
不過@Scheduled 可以進行兩種配置,我們熟悉的cron ,還有一種是fixedRate。比如fixedRate=6000 表示方法每6秒鐘執行一次。
我們來啟動項目看一下,可以看到兩個方法都在定期執行。
基于接口
上面可以看到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 * * * * ?');
在dao 層mapper1包下創建一個CronMapper接口,很簡單的就獲取cron
public interface CronMapper { @Select("select cron from scheduled where cron_id = #{id}") public String getCron(int id);}
這里我們就不寫service 層了。直接在autotask 包下創建一個AutoTaskFromDB類
@Slf4j@Componentpublic 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 是從數據庫讀取的。
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的整數 * - , /
常例
每隔5秒鐘執行一次 */5 * * * * ? 每隔1分鐘執行一次 0 * /1 * * * ? 每天1點執行一次 0 0 1 * * ? 每天23點55分執行一次 0 55 23 * * ? 每月最后一天23點執行一次 0 0 23 L * ? 每周六8點執行一次 0 0 8 ? * L 每月最后一個周五,每隔2小時執行一次 0 0 */2 ? * 6L 每月的第三個星期五上午10:15執行一次 0 15 10 ? * 5#3 在每天下午2點到下午2:05期間的每1分鐘執行 0 0-5 14 * * ? 表示周一到周五每天上午10:15執行 0 15 10 ? * 2-6 每個月的最后一個星期五上午10:15執行 0 15 10 ? * 6L 每天上午10點,下午2點,4點執行一次 0 0 10,14,16 * * ? 朝九晚五工作時間內每半小時執行一次 0 0/30 9-17 * * ? 每個星期三中午12點執行一次 0 0 12 ? * 4 每年三月的星期三的下午2:10和2:44各執行一次 0 10,44 14 ? 3 4 每月的第三個星期五上午10:15執行一次 0 15 10 ? * 6#3 每月一日凌晨2點30執行一次 0 30 2 1 * ? 每分鐘的第10秒與第20秒都會執行 10,20 * * * * ? 每月的第2個星期的周5,凌晨執行 0 0 0 ? * 6#2
番外
本來這個知識點不應該放在這里講的,但是不多,順帶寫了,剛好也能做定時器。我們項目中往往有一些需求需要在項目啟動的時候就執行,那這個我們怎么實現了。其實spring boot 使用起來也非常簡單,只用實現 ApplicationRunner 就好了。
我們在autotask 包下創建一個AutoTaskFromSpringRunner類
@Slf4j@Componentpublic class AutoTaskFromSpringRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { process(); } private void process(){ log.info(" run ApplicationArguments"); }}
那這個怎么用來做定時器呢?當然是結合線程來做啦,但是這個方法其實不建議,b畢竟線程很容易出問題,但是提供一種思路:啟動項目看一下,可以發現這個會在項目啟動后執行,但是只會執行一次。
@Slf4j@Componentpublic 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("線程定時器"); }}
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。