專案經常會用到定時任務,springboot自然是可以通過整合相關組件來實作的,
目前常用的定時任務的實作有兩種:
- 通過spring 自帶的定時器任務@Schedule來實作
- 通過Quartz來實作
本次借用上一篇《spring boot 整合Mybatis》的既有專案結構進行案例除錯,
一、cron運算式
無論上面說的哪種實作方式,都需要用到cron運算式,因此不得不先介紹下它,
Cron運算式是一個字串,由6或7個域組成,每個域有不同的含義,每個域之間用空格隔開,有2中格式:
Seconds Minutes Hours DayofMonth Month DayofWeek Year (7個域)
Seconds Minutes Hours DayofMonth Month DayofWeek (6個域)
每個域可能出現的值:
Seconds:有效范圍為0-59的整數
Minutes:有效范圍為0-59的整數
Hours:有效范圍為0-23的整數
DayofMonth:有效范圍為0-31的整數
Month:有效范圍為1-12的整數或JAN-DEC
DayofWeek:有效范圍為1-7的整數或SUN-SAT兩個范圍,1表示星期天,2表示星期一, 依次類推
Year:有效范圍為1970-2099年
除了以上內容外,還可能出現一些特殊字符:
(1)*:表示匹配該域的任意值,假如在Minutes域使用*, 即表示每分鐘都會觸發事件,
(2)?:只能用在DayofMonth和DayofWeek兩個域,它也匹配域的任意值,但實際不會,因為DayofMonth和DayofWeek會相互影響,例如想在每月的10日觸發調度,不管10日到底是星期幾,則只能使用如下寫法: 13 13 15 10 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期幾都會觸發,實際上并不是這樣,
(3)-:表示范圍,例如在Minutes域使用5-20,表示從5分到20分鐘每分鐘觸發一次
(4)/:表示起始時間開始觸發,然后每隔固定時間觸發一次,例如在Minutes域使用5/20,則意味著5分鐘觸發一次,而25,45等分別觸發一次.
(5),:表示列出列舉值值,例如:在Minutes域使用5,20,則意味著在5和20分每分鐘觸發一次,
(6)L:表示最后,只能出現在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味著在最后的一個星期四觸發,
(7)W:表示有效作業日(周一到周五),只能出現在DayofMonth域,系統將在離指定日期的最近的有效作業日觸發事件,例如:在 DayofMonth使用5W,如果5日是星期六,則將在最近的作業日:星期五,即4日觸發,如果5日是星期天,則在6日(周一)觸發;如果5日在星期一到星期五中的一天,則就在5日觸發,另外一點,W的最近尋找不會跨過月份
(8)LW:這兩個字符可以連用,表示在某個月最后一個作業日,即最后一個星期五,
(9)#:用于確定每個月第幾個星期幾,只能出現在DayofMonth域,例如在4#2,表示某月的第二個星期三,
舉例:
@Scheduled(cron = “0 0 1 1 1 ?”)//每年一月的一號的 1:00:00 執行一次
@Scheduled(cron = “0 0 1 1 1,6 ?”) //一月和六月的一號的 1:00:00 執行一次
@Scheduled(cron = “0 0 1 1 1,4,7,10 ?”) //每個季度的第一個月的一號的 1:00:00 執行一次
@Scheduled(cron = “0 0 1 1 * ?”)//每月一號 1:00:00 執行一次
@Scheduled(cron=“0 0 1 * * *”) //每天凌晨 1 點執行一次
以上看上去有點復雜,不過不用擔心,記住常用的就行了,另外,現在網上還有 在線Cron運算式生成器可以幫助我們設定確定相關運算式內容,
二、@Schedule實作
1.引入依賴
<!--添加schedule依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
2.代碼實作
-
新建類JdkSchedule
@Component public class JdkSchedule { @Autowired UserService userService; @Scheduled(cron = "0/2 * * * * ?") //每個兩秒觸發一次 public void scheduleGetUserList() { System.out.println("**觸發JDK 定時器***"); List<User> list = userService.getUserList(new User()); for (User user :list ){ System.out.println(user.toString()); } } }里面的userService為上一次添加的內容
-
啟動類添加注解,啟動定時任務
@EnableScheduling
3.測驗效果
每隔兩秒列印一次:
**觸發JDK 定時器***
User{id=1, name='sam', age=32}
User{id=2, name='hah ', age=10}
三、Quartz實作
1.Quartz介紹
Quartz是一個完全由Java撰寫的開源任務調度的框架,通過觸發器設定作業定時運行規則,控制作業的運行時間,它包括調度器、觸發器、作業,
| 組成 | 描述 |
|---|---|
| Job--任務 | 做什么事? |
| Trigger--觸發器 | 什么時候做? |
| Scheduler--調度器 | 什么時候需要去做什么事情? |
2.基本使用
-
引入依賴
<!--引入quartz依賴--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> -
創建job類
public class MyJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("...quartz job 觸發執行..."); } }需要實作Quartz的Job介面
-
撰寫測驗類:
/** * quartz原生態用法 */ public class JobTestMain { public static void main(String[] args) throws SchedulerException { //1.創建job JobDetail job = JobBuilder.newJob(MyJob.class).build(); //2.創建trigger CronTrigger trigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?")) .build(); //3.創建schedule Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.scheduleJob(job, trigger); scheduler.start(); } } -
執行測驗類JobTestMain:
每三秒列印一次:
...quartz job 觸發執行...
3.springboot整合使用
-
引入依賴
<!--添加schedule依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!--引入quartz依賴--> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <!--引入spring tx依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency>springboot整合的時候,需要添加這三個依賴,
-
撰寫配置類
/** * springboot整合quartz使用方法 */ @Configuration public class QuartzConfig { /** * 創建job物件 * @return */ @Bean public JobDetailFactoryBean jobDetailFactoryBean() { JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setJobClass(MyJob.class); return jobDetailFactoryBean; } /** * 創建trigger物件 - cron運算式物件 * @param jobDetailFactoryBean * @return */ @Bean public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean){ CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setCronExpression("0/5 * * * * ?"); // 關聯JobDetail物件 cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject()); return cronTriggerFactoryBean; } /** * 創建trigger物件 - 一般物件 * @param jobDetailFactoryBean * @return */ @Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) { SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean(); // 關聯JobDetail物件 simpleTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject()); // 設定重復次數,這里配置的是重復次數,而不是總次數; 總次數=重復次數+1,也就是說這里配置的次數是:執行完一次之后,再重復執行的次數 simpleTriggerFactoryBean.setRepeatCount(1); // 設定間隔時間 simpleTriggerFactoryBean.setRepeatInterval(2000); return simpleTriggerFactoryBean; } /** * 創建schedule物件 * @param triggerFactoryBean * @return */ @Bean public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean triggerFactoryBean){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setTriggers(triggerFactoryBean.getObject()); return schedulerFactoryBean; } }這里需要注意下,schedulerFactoryBean()方法中傳入的引數如果是CronTriggerFactoryBean,則執行的是cronTriggerFactoryBean()對應的設定;引數如果是SimpleTriggerFactoryBean,則執行的是simpleTriggerFactoryBean()對應的設定,
-
啟動類添加注解
@EnableScheduling
-
測驗效果
每5秒鐘執行一次:
...quartz job 觸發執行...
如果前面的@Schedule和這里的Quartz的定時任務放在一起了,則執行效果為兩個Job一起執行:
...quartz job 觸發執行... User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} **觸發JDK 定時器*** User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} **觸發JDK 定時器*** User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} **觸發JDK 定時器*** ...quartz job 觸發執行... User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} **觸發JDK 定時器*** User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} **觸發JDK 定時器*** User{id=1, name='sam', age=32} User{id=2, name='hah ', age=10} ...quartz job 觸發執行...
以上即為本文全部內容,
本文來自博客園,作者:JAVA開發老菜鳥,轉載請注明原文鏈接:https://www.cnblogs.com/sam-uncle/p/15238215.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/298233.html
標籤:Java
上一篇:作業系統的IO模型
下一篇:并發編程之:JUC并發控制工具
