SpringBoot項(xiàng)目使用@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)的方法
SpringBoot項(xiàng)目【使用@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)】
使用SpringBoot創(chuàng)建定時(shí)任務(wù)目前主要有以下三種創(chuàng)建方式:
1、基于注解(@Scheduled)
- 最簡(jiǎn)單直接
2、基于接口(SchedulingConfigurer)- 適于實(shí)際使用中從數(shù)據(jù)庫(kù)中讀取指定時(shí)間來(lái)動(dòng)態(tài)執(zhí)行定時(shí)任務(wù)
3、基于注解設(shè)定多線程定時(shí)任務(wù)
1. 基于注解(@Scheduled)
1.1 @Scheduled 注解和 @EnableScheduling 注解的使用
基于注解@Scheduled默認(rèn)為單線程,開(kāi)啟多個(gè)任務(wù)時(shí),任務(wù)的執(zhí)行會(huì)受上一個(gè)任務(wù)執(zhí)行時(shí)間影響
@EnableScheduling注解: 在配置類上使用,開(kāi)啟計(jì)劃任務(wù)的支持(類上)。
@Scheduled注解: 來(lái)聲明這是一個(gè)任務(wù),包括 cron,fixDelay,fixRate 等類型(方法上,需先開(kāi)啟計(jì)劃任務(wù)的支持)。
【示例】SpringBoot項(xiàng)目中使用@Scheduled注解和@EnableScheduling注解實(shí)現(xiàn)定時(shí)任務(wù)。
(1)開(kāi)啟定時(shí)任務(wù)
SpringBoot 項(xiàng)目在項(xiàng)目啟動(dòng)類上添加 @EnableScheduling 注解即可開(kāi)啟定時(shí)任務(wù)管理。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling //開(kāi)啟定時(shí)任務(wù) public class ScheduledDemoApplication { public static void main(String[] args) { SpringApplication.run(ScheduledDemoApplication.class, args); } }
(2)創(chuàng)建定時(shí)任務(wù)
創(chuàng)建定時(shí)任務(wù),并使用 @Scheduled 注解。
package com.pjb.Schedule; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; /** * 定時(shí)任務(wù)的使用 * @author pan_junbiao **/ @Component public class Task { @Scheduled(cron="0/5 * * * * ? ") //每5秒執(zhí)行一次 public void execute(){ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //設(shè)置日期格式 System.out.println("歡迎訪問(wèn) pan_junbiao的博客 " + df.format(new Date())); } }
1.2 @Scheduled 注解各參數(shù)講解
@Scheduled
注解具有多個(gè)參數(shù),以下是常用的幾個(gè)參數(shù):
cron
接收一個(gè) cron 表達(dá)式。cron 表達(dá)式由六個(gè)或七個(gè)域組成,常見(jiàn)的格式如下:
css
復(fù)制編輯
[秒] [分] [小時(shí)] [日] [月] [周] [年]
序號(hào) | 說(shuō)明 | 是否必填 | 允許填寫的值 | 允許的通配符 |
---|---|---|---|---|
1 | 秒 | 是 | 0-59 | , - * / |
2 | 分 | 是 | 0-59 | , - * / |
3 | 小時(shí) | 是 | 0-23 | , - * / |
4 | 日 | 是 | 1-31 | , - * ? / L W |
5 | 月 | 是 | 1-12 or JAN-DEC | , - * / |
6 | 周 | 是 | 1-7 or SUN-SAT | , - * ? / L # |
7 | 年 | 否 | 空或1970-2099 | , - * / |
通配符說(shuō)明:
? 表示不指定值。使用的場(chǎng)景為不需要關(guān)心當(dāng)前設(shè)置這個(gè)字段的值。例如:要在每月的10號(hào)觸發(fā)一個(gè)操作,但不關(guān)心是周幾,所以需要周位置的那個(gè)字段設(shè)置為"?" 具體設(shè)置為 0 0 0 10 * ?
-表示區(qū)間。例如 在小時(shí)上設(shè)置 “10-12”,表示 10,11,12點(diǎn)都會(huì)觸發(fā)。
, 表示指定多個(gè)值,例如在周字段上設(shè)置 “MON,WED,FRI” 表示周一,周三和周五觸發(fā)
/ 用于遞增觸發(fā)。如在秒上面設(shè)置"5/15" 表示從5秒開(kāi)始,每增15秒觸發(fā)(5,20,35,50)。在月字段上設(shè)置’1/3’所示每月1號(hào)開(kāi)始,每隔三天觸發(fā)一次。
L 表示最后的意思。在日字段設(shè)置上,表示當(dāng)月的最后一天(依據(jù)當(dāng)前月份,如果是二月還會(huì)依據(jù)是否是潤(rùn)年[leap]), 在周字段上表示星期六,相當(dāng)于"7"或"SAT"。如果在"L"前加上數(shù)字,則表示該數(shù)據(jù)的最后一個(gè)。例如在周字段上設(shè)置"6L"這樣的格式,則表示“本月最后一個(gè)星期五"
W 表示離指定日期的最近那個(gè)工作日(周一至周五). 例如在日字段上設(shè)置"15W",表示離每月15號(hào)最近的那個(gè)工作日觸發(fā)。(注,“W"前只能設(shè)置具體的數(shù)字,不允許區(qū)間”-")
常用示例:
定時(shí)任務(wù)表達(dá)式 | 描述 |
---|---|
0 0 12 * * ? | 每天12點(diǎn)觸發(fā) |
0 15 10 ? * * | 每天10點(diǎn)15分觸發(fā) |
0 15 10 * * ? | 每天10點(diǎn)15分觸發(fā) |
0 15 10 * * ? * | 每天10點(diǎn)15分觸發(fā) |
0 15 10 * * ? 2025 | 2025年每天10點(diǎn)15分觸發(fā) |
0 * 14 * * ? | 每天下午的 2點(diǎn)到2點(diǎn)59分每分觸發(fā) |
0 0/5 14 * * ? | 每天下午的 2點(diǎn)到2點(diǎn)59分(整點(diǎn)開(kāi)始,每隔5分觸發(fā)) |
0 0/5 14,18 * * ? | 每天下午的 2點(diǎn)到2點(diǎn)59分(整點(diǎn)開(kāi)始,每隔5分觸發(fā))每天下午的 18點(diǎn)到18點(diǎn)59分(整點(diǎn)開(kāi)始,每隔5分觸發(fā)) |
0 0-5 14 * * ? | 每天下午的 2點(diǎn)到2點(diǎn)05分每分觸發(fā) |
0 10,44 14 ? 3 WED | 3月分每周三下午的 2點(diǎn)10分和2點(diǎn)44分觸發(fā) |
0 15 10 ? * MON-FRI | 從周一到周五每天上午的10點(diǎn)15分觸發(fā) |
0 15 10 15 * ? | 每月15號(hào)上午10點(diǎn)15分觸發(fā) |
0 15 10 L * ? | 每月最后一天的10點(diǎn)15分觸發(fā) |
0 15 10 ? * 6L | 每月最后一周的星期五的10點(diǎn)15分觸發(fā) |
0 15 10 ? * 6L 2022-2025 | 從2022年到2025年每月最后一周的星期五的10點(diǎn)15分觸發(fā) |
0 15 10 ? * 6#3 | 每月的第三周的星期五開(kāi)始觸發(fā) |
0 0 12 1/5 * ? | 每月的第一個(gè)中午開(kāi)始每隔5天觸發(fā)一次 |
0 11 11 11 11 ? | 每年的11月11號(hào) 11點(diǎn)11分觸發(fā)(光棍節(jié)) |
其他常用
- fixedDelay: 上次任務(wù)完成后多少毫秒再執(zhí)行。
- fixedRate: 上次任務(wù)開(kāi)始后多少毫秒再執(zhí)行。
- initialDelay: 第一次延遲多少毫秒后再執(zhí)行。
2. 動(dòng)態(tài)定時(shí)任務(wù):基于接口(SchedulingConfigurer)
2.1 創(chuàng)建數(shù)據(jù)庫(kù)表
在 MySQL 數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè) cron 表,存儲(chǔ)定時(shí)任務(wù)的 cron 表達(dá)式:
DROP TABLE IF EXISTS cron; CREATE TABLE cron ( cron_id VARCHAR(30) NOT NULL PRIMARY KEY, cron VARCHAR(30) NOT NULL ); INSERT INTO cron VALUES ('1', '0/5 * * * * ?');
2.2 添加 MyBatis 依賴
在 pom.xml
中添加 MyBatis 和 MySQL 的 JDBC 依賴:
<!-- MyBatis與SpringBoot整合依賴 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!-- MySQL的JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency>
2.3 創(chuàng)建定時(shí)任務(wù)配置類
package com.pjb.config; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.util.StringUtils; import java.time.LocalDateTime; /** * 動(dòng)態(tài)定時(shí)任務(wù)配置類 * @author pan_junbiao **/ @Configuration @EnableScheduling public class DynamicScheduleConfigurer implements SchedulingConfigurer { @Mapper public interface CronMapper { @Select("select cron from cron limit 1") public String getCron(); } @Autowired CronMapper cronMapper; @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask( () -> System.out.println("歡迎訪問(wèn) pan_junbiao的博客: " + LocalDateTime.now().toLocalTime()), triggerContext -> { String cron = cronMapper.getCron(); if (StringUtils.isEmpty(cron)) { // 錯(cuò)誤處理 } return new CronTrigger(cron).nextExecutionTime(triggerContext); } ); } }
3. 基于注解設(shè)定多線程定時(shí)任務(wù)
通過(guò) @Async
注解開(kāi)啟多線程定時(shí)任務(wù),解決多個(gè)任務(wù)執(zhí)行時(shí)相互影響的問(wèn)題。
創(chuàng)建多線程定時(shí)任務(wù)
package com.pjb.Task; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; /** * 基于注解設(shè)定多線程定時(shí)任務(wù) * @author pan_junbiao */ @Component @EnableScheduling // 開(kāi)啟定時(shí)任務(wù) @EnableAsync // 開(kāi)啟多線程 public class MultithreadScheduleTask { @Async @Scheduled(fixedDelay = 1000) // 間隔1秒 public void first() throws InterruptedException { System.out.println("第一個(gè)定時(shí)任務(wù)開(kāi)始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName()); Thread.sleep(1000 * 10); } @Async @Scheduled(fixedDelay = 2000) public void second() { System.out.println("第二個(gè)定時(shí)任務(wù)開(kāi)始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName()); } }
注意
由于 @Scheduled
默認(rèn)是單線程模式,開(kāi)啟多個(gè)定時(shí)任務(wù)時(shí)任務(wù)的執(zhí)行順序會(huì)受前一個(gè)任務(wù)的執(zhí)行時(shí)間影響。通過(guò) @Async
注解,我們可以解決這個(gè)問(wèn)題,使多個(gè)定時(shí)任務(wù)并行執(zhí)行。
通過(guò)以上三種方式,Spring Boot 提供了靈活的定時(shí)任務(wù)支持,可以根據(jù)項(xiàng)目需求選擇合適的實(shí)現(xiàn)方式。
到此這篇關(guān)于SpringBoot項(xiàng)目使用@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)的文章就介紹到這了,更多相關(guān)SpringBoot @Scheduled定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot的@Scheduled和@Schedules區(qū)別小結(jié)
- SpringBoot中@Scheduled實(shí)現(xiàn)服務(wù)啟動(dòng)時(shí)執(zhí)行一次
- @Scheduled在springboot中的使用方式
- springboot實(shí)現(xiàn)定時(shí)任務(wù)@Scheduled方式
- SpringBoot中@Scheduled()注解以及cron表達(dá)式詳解
- springboot Quartz動(dòng)態(tài)修改cron表達(dá)式的方法
- SpringBoot?@Scheduled?Cron表達(dá)式使用方式
相關(guān)文章
java學(xué)習(xí)指南之字符串與正則表達(dá)式
在日常Java后端開(kāi)發(fā)過(guò)程中,免不了對(duì)數(shù)據(jù)字段的解析,自然就少不了對(duì)字符串的操作,這其中就包含了正則表達(dá)式這一塊的內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于java學(xué)習(xí)指南之字符串與正則表達(dá)式的相關(guān)資料,需要的朋友可以參考下2023-05-05Spring JPA聯(lián)表查詢之OneToOne源碼詳解
這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToOne源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Springboot整合JwtHelper實(shí)現(xiàn)非對(duì)稱加密
本文主要介紹了Springboot整合JwtHelper實(shí)現(xiàn)非對(duì)稱加密,主要介紹兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03SpringBoot ThreadLocal 簡(jiǎn)單介紹及使用詳解
ThreadLocal 叫做線程變量,意思是 ThreadLocal 中填充的變量屬于當(dāng)前線程,該變量對(duì)其他線程而言是隔離的,也就是說(shuō)該變量是當(dāng)前線程獨(dú)有的變量,這篇文章主要介紹了SpringBoot ThreadLocal 的詳解,需要的朋友可以參考下2024-01-01JMeter中的后端監(jiān)聽(tīng)器的實(shí)現(xiàn)
本文主要介紹了JMeter中的后端監(jiān)聽(tīng)器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09Springboot集成Spring Security實(shí)現(xiàn)JWT認(rèn)證的步驟詳解
這篇文章主要介紹了Springboot集成Spring Security實(shí)現(xiàn)JWT認(rèn)證的步驟詳解,幫助大家更好的理解和使用springboot,感興趣的朋友可以了解下2021-02-02java實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘并設(shè)置鬧鐘功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘并設(shè)置鬧鐘功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01