1. 程式人生 > >使用Spring Task完成定時任務

使用Spring Task完成定時任務

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>
        &lt;!&ndash;每5秒鐘執行一次&ndash;&gt;
        <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 
版權宣告:本文為博主原創文章,轉載請附上博文連結!