SpringBoot 創(chuàng)建定時(shí)任務(wù)
點(diǎn)擊關(guān)注公眾號,Java干貨及時(shí)送達(dá)
牛逼!又發(fā)現(xiàn)了一款面試題庫,太全了!!
(點(diǎn)擊查看)
SpringBoot 創(chuàng)建定時(shí)任務(wù)
創(chuàng)建定時(shí)任務(wù)非常簡單,主要有兩種創(chuàng)建方式:
一、基于注解(@Scheduled) ?
二、基于接口(SchedulingConfigurer).
前者相信大家都很熟悉,但是實(shí)際使用中我們往往想從數(shù)據(jù)庫中讀取指定時(shí)間來動(dòng)態(tài)執(zhí)行定時(shí)任務(wù),這時(shí)候基于接口的定時(shí)任務(wù)就大派用場了。
一、靜態(tài)定時(shí)任務(wù)(基于注解)
“基于注解來創(chuàng)建定時(shí)任務(wù)非常簡單,只需幾行代碼便可完成。
”
@Scheduled 除了支持靈活的參數(shù)表達(dá)式cron之外,還支持簡單的延時(shí)操作,例如 fixedDelay ,fixedRate 填寫相應(yīng)的毫秒數(shù)即可。
@Configuration?//1.主要用于標(biāo)記配置類,兼?zhèn)銫omponent的效果。
@EnableScheduling?//?2.開啟定時(shí)任務(wù)
public?class?SimpleScheduleConfig?{
????//3.添加定時(shí)任務(wù)
????@Scheduled(cron?=?"0/5?*?*?*?*??")
????private?void?configureTasks()?{
????????System.err.println("執(zhí)行定時(shí)任務(wù)1:?"?+?LocalDateTime.now());
????}
}
“Cron表達(dá)式參數(shù)分別表示:
秒(0~59) 例如0/5表示每5秒?
分(0~59)?
時(shí)(0~23)?
月的某天(0~31) 需計(jì)算?
月(0~11)?
周幾( 可填1-7 ?或 SUN/MON/TUE/WED/THU/FRI/SAT)
”
啟動(dòng)應(yīng)用,可以看到控制臺的信息如下:
誠然,使用Scheduled 確實(shí)很方便,但缺點(diǎn)是當(dāng)我們調(diào)整了執(zhí)行周期的時(shí)候,需要重啟應(yīng)用才能生效,這多少有些不方便。為了達(dá)到實(shí)時(shí)生效的效果,可以使用接口來完成定時(shí)任務(wù)。
二、動(dòng)態(tài)定時(shí)任務(wù)(基于接口)
為了演示效果,這里選用 Mysql數(shù)據(jù)庫 和 Mybatis 來查詢和調(diào)整定時(shí)任務(wù)的執(zhí)行周期,然后觀察定時(shí)任務(wù)的執(zhí)行情況。
1.引入依賴
<dependencies>
????<dependency>
????????<groupId>org.springframework.bootgroupId>
????????<artifactId>spring-boot-starter-webartifactId>
????dependency>
????<dependency>
????????<groupId>org.mybatis.spring.bootgroupId>
????????<artifactId>mybatis-spring-boot-starterartifactId>
????????<version>1.3.1version>
????dependency>
????<dependency>
????????<groupId>mysqlgroupId>
????????<artifactId>mysql-connector-javaartifactId>
????????<scope>runtimescope>
????dependency>
????<dependency>
????????<groupId>org.springframework.bootgroupId>
????????<artifactId>spring-boot-starter-testartifactId>
????????<scope>testscope>
????dependency>
dependencies>
2.添加數(shù)據(jù)庫記錄
在Navicat 連接本地?cái)?shù)據(jù)庫,隨便打開查詢窗口,然后執(zhí)行腳本內(nèi)容,如下:
DROP?DATABASE?IF?EXISTS?`socks`;
CREATE?DATABASE?`socks`;
USE?`SOCKS`;
DROP?TABLE?IF?EXISTS?`cron`;
CREATE?TABLE?`cron`??(
??`cron_id`?varchar(30),
??`cron`?varchar(30)?
);
INSERT?INTO?`cron`?VALUES?('1',?'0/5?*?*?*?*??');
然后在項(xiàng)目中的application.yml 添加數(shù)據(jù)源:
#application.yml 配置如下:
spring:
??datasource:
????url:?jdbc:mysql://localhost:3306/socks?useSSL=false
????username:?root
????password:?root
3.創(chuàng)建定時(shí)器
數(shù)據(jù)庫準(zhǔn)備好數(shù)據(jù)之后,我們編寫定時(shí)任務(wù),注意這里添加的是TriggerTask,目的是循環(huán)讀取我們在數(shù)據(jù)庫設(shè)置好的執(zhí)行周期,以及執(zhí)行相關(guān)定時(shí)任務(wù)的內(nèi)容。具體代碼如下:
@Configuration
@EnableScheduling
public?class?CompleteScheduleConfig?implements?SchedulingConfigurer?{
????@Mapper
????public?interface?CronMapper?{
????????@Select("select?cron?from?cron?limit?1")
????????String?getCron();
????}
????@Autowired
????@SuppressWarnings("all")
????CronMapper?cronMapper;
????/**
?????*?執(zhí)行定時(shí)任務(wù).
?????*/
????@Override
????public?void?configureTasks(ScheduledTaskRegistrar?taskRegistrar)?{
????????taskRegistrar.addTriggerTask(
????????????????//1.添加任務(wù)內(nèi)容(Runnable)
????????????????()?->?System.out.println("執(zhí)行定時(shí)任務(wù)2:?"?+?LocalDateTime.now().toLocalTime()),
????????????????//2.設(shè)置執(zhí)行周期(Trigger)
????????????????triggerContext?->?{
????????????????????//2.1?從數(shù)據(jù)庫獲取執(zhí)行周期
????????????????????String?cron?=?cronMapper.getCron();
????????????????????//2.2?合法性校驗(yàn).
????????????????????if?(StringUtils.isEmpty(cron))?{
????????????????????????//?Omitted?Code?..
????????????????????}
????????????????????//2.3?返回執(zhí)行周期(Date)
????????????????????return?new?CronTrigger(cron).nextExecutionTime(triggerContext);
????????????????}
????????);
????}
}
4. 動(dòng)態(tài)修改執(zhí)行周期
啟動(dòng)應(yīng)用后,查看控制臺,打印時(shí)間是我們預(yù)期的每5秒一次:
然后打開Navicat ,將執(zhí)行周期修改為每1秒執(zhí)行一次,如圖:
查看控制臺,發(fā)現(xiàn)執(zhí)行周期已經(jīng)改變,并且不需要我們重啟應(yīng)用,十分方便。如圖:
如有文章對你有幫助,
歡迎關(guān)注??、點(diǎn)贊??、轉(zhuǎn)發(fā)??!
推薦,?Java面試題庫,詳情點(diǎn)擊: 牛逼!又發(fā)現(xiàn)了一款牛逼的Java面試題庫,史上最強(qiáng)! 點(diǎn)擊文末“閱讀原文”可直達(dá)







