1. 前言
上一篇我們學習了Quartz作為定時任務的框架的使用, 這一篇我們來學習Spring全家桶的SpringTask, 對于主張簡單易用的Spring家族來說, SpringTask無疑也是一個輕量級的框架,他比Quartz更容易上手.
2. pom.xml依賴
? <dependencies>
? ? <dependency>
? ? ? <groupId>org.springframework</groupId>
? ? ? <artifactId>spring-context</artifactId>
? ? ? <version>4.3.12.RELEASE</version>
? ? </dependency>
? ? <dependency>
? ? ? <groupId>org.springframework</groupId>
? ? ? <artifactId>spring-context-support</artifactId>
? ? ? <version>4.3.12.RELEASE</version>
? ? </dependency>
? ? <dependency>
? ? ? <groupId>junit</groupId>
? ? ? <artifactId>junit</artifactId>
? ? ? <version>4.12</version>
? ? </dependency>
? ? <dependency>
? ? ? <groupId>org.springframework</groupId>
? ? ? <artifactId>spring-test</artifactId>
? ? ? <version>4.3.12.RELEASE</version>
? ? </dependency>
? </dependencies>
?
對的,一個spring-context就是他所需要的框架了, 也就是說, 如果你現在開發的項目是用的spring ,無需管依賴,直接看下一步就可以了.
2. 實現代碼
spring 的老套路, 一般都可以用兩種方式實現: 一是配置方式,二是注解方式
2.1 基于xml配置文件的方式
1 . 寫一個運行任務的job類
package com.zgd.spring.task;
import java.util.Date;
/**
?* xml配置方式的定時任務
?*/
public class XmlTask {
? ? /**
? ? ?* 要執行的任務
? ? ?*/
? ? public void task(){
? ? ? ? System.out.println("定時任務執行中: "+new Date().toLocaleString());
? ? }
}
?
2 .在resource文件夾中, 創建spring 的配置文件: spring.xml , 這里特意要注意beans中的命名空間不能少
<beans xmlns="http://www.springframework.org/schema/beans"
? ? ? ?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? ?xmlns:task="http://www.springframework.org/schema/task"
? ? ? ?xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans
? http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
? http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
<bean id="xmlTask" class="com.zgd.spring.task.XmlTask"/>
? ? <task:scheduled-tasks>
? ? ? ? <!--每5秒鐘運行一次-->
? ? ? ? <task:scheduled ref="xmlTask" method="task" cron="0/5 * * * * ?"/>
? ? </task:scheduled-tasks>
</beans>
?
關于cron的語法:?
Cron表達式是一個字符串,字符串以5或6個空格隔開,分為6或7個域,每一個域代表一個含義,Cron有如下兩種語法格式:
(1)Seconds ?Minutes ?Hours ?DayofMonth ?Month ?DayofWeek ?Year
(2)Seconds ?Minutes ?Hours ?DayofMonth ?Month ?DayofWeek
每一個域可出現的字符如下:?
Seconds:可出現", - * /"四個字符,有效范圍為0-59的整數?
Minutes:可出現", - * /"四個字符,有效范圍為0-59的整數?
Hours:可出現", - * /"四個字符,有效范圍為0-23的整數?
DayofMonth:可出現", - * / ? L W C"八個字符,有效范圍為1-31的整數?
Month:可出現", - * /"四個字符,有效范圍為1-12的整數或JAN-DEc ? ?
DayofWeek:可出現", - * / ? L C #"四個字符,有效范圍為1-7的整數或SUN-SAT兩個范圍。1表示星期天,2表示星期一, 依次類推?
Year:可出現", - * /"四個字符,有效范圍為1970-2099年
每一個域都使用數字,但還可以出現如下特殊字符,它們的含義是:?
(1)*:表示匹配該域的任意值,假如在Minutes域使用*, 即表示每分鐘都會觸發事件。
(2)?:只能用在DayofMonth和DayofWeek兩個域。它也匹配域的任意值,但實際不會。因為DayofMonth和 DayofWeek會相互影響。例如想在每月的20日觸發調度,不管20日到底是星期幾,則只能使用如下寫法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用*,如果使用*表示不管星期幾都會觸發,實際上并不是這樣。?
(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,表示某月的第二個星期三。
?
舉例如下:
?<!-- 每半分鐘觸發任務 -->
?<task:scheduled ref="app" method="execute1" cron="30 * * * * ?"/>
?<!-- 每小時的10分30秒觸發任務 -->
?<task:scheduled ref="app" method="execute2" cron="30 10 * * * ?"/>
?<!-- 每天1點10分30秒觸發任務 -->
?<task:scheduled ref="app" method="execute3" cron="30 10 1 * * ?"/>
?<!-- 每月20號的1點10分30秒觸發任務 -->
?<task:scheduled ref="app" method="execute4" cron="30 10 1 20 * ?"/>
?<!-- 每年10月20號的1點10分30秒觸發任務 -->
?<task:scheduled ref="app" method="execute5" cron="30 10 1 20 10 ?"/>
?<!-- 每15秒、30秒、45秒時觸發任務 -->
?<task:scheduled ref="app" method="execute6" cron="15,30,45 * * * * ?"/>
?<!-- 15秒到45秒每隔1秒觸發任務 -->
?<task:scheduled ref="app" method="execute7" cron="15-45 * * * * ?"/>
?<!-- 每分鐘的每15秒時任務任務,每隔5秒觸發一次 -->
?<task:scheduled ref="app" method="execute8" cron="15/5 * * * * ?"/>
?<!-- 每分鐘的15到30秒之間開始觸發,每隔5秒觸發一次 -->
?<task:scheduled ref="app" method="execute9" cron="15-30/5 * * * * ?"/>
?<!-- 每小時的0分0秒開始觸發,每隔3分鐘觸發一次 -->
?<task:scheduled ref="app" method="execute10" cron="0 0/3 * * * ?"/>
?<!-- 星期一到星期五的10點15分0秒觸發任務 -->
?<task:scheduled ref="app" method="execute11" cron="0 15 10 ? * MON-FRI"/>
?
然后我們需要一個測試類來測試:
package com.zgd.spring;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class App{
? ? @Test
? ? public void start(){
? ? ? ? System.out.println("啟動spring");
? ? ? ? while (true){
? ? ? ? ? ? //使用死循環確保程序持續的運行
? ? ? ? }
? ? }
}
?
運行結果:?
2.2 基于@Scheduled注解的方式
這個注解可以傳五個參數:
cron:指定cron表達式
zone:官方文檔解釋:A time zone for which the cron expression will be resolved。指定cron表達式運行的時區
fixedDelay:官方文檔解釋:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示從上一個任務完成開始到下一個任務開始的間隔,單位是毫秒。
fixedRate:官方文檔解釋:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即從上一個任務開始到下一個任務開始的間隔,單位是毫秒。
initialDelay:官方文檔解釋:Number of milliseconds to delay before the first execution of a fixedRate() or fixedDelay() task.任務第一次被調用前的延時,單位毫秒?
再寫一個任務類:
package com.zgd.spring.task;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
?* 注解執行的任務
?*/
@Component
public class AnnoTask {
? ? /**
? ? ?* 使用注解,5秒執行一次
? ? ?*/
? ? @Scheduled(cron = "0/5 * * * * ?")
? ? public void task(){
? ? ? ? System.out.println("注解的方式的任務執行了" + new Date().toLocaleString());
? ? }
}
?
2 . 在spring配置文件頭中添加命名空間及描述,并開啟定時任務注解驅動
<beans xmlns="http://www.springframework.org/schema/beans"
? ? ? ?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
? ? ? ?xmlns:task="http://www.springframework.org/schema/task"
? ? ? ?xmlns:context="http://www.springframework.org/schema/context"
? ? ? ?xsi:schemaLocation="http://www.springframework.org/schema/beans
? http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
? http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
? ? <bean id="xmlTask" class="com.zgd.spring.task.XmlTask"/>
? ?<!-- <task:scheduled-tasks>
? ? ? ? <!–每5秒鐘運行一次–>
? ? ? ? <task:scheduled ref="xmlTask" method="task" cron="0/5 * * * * ?"/>
? ? </task:scheduled-tasks>-->
? ? <task:annotation-driven />
? ? <context:component-scan base-package="com.zgd.spring.task"/>
</beans>
?
這里我試了一下,怎么都無法執行定時任務, 后面仔細檢查,發現是沒有加上注解的自動掃描, 平時開發肯定都會加上這個,但是由于是測試demo所以把這個忘記了.?
<context:component-scan base-package="com.zgd.spring.task"/>
運行我們的測試類, 結果如下?
---------------------?
作者:zzzgd_666?
來源:CSDN?
原文:https://blog.csdn.net/zzzgd_666/article/details/80723654?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!