SpringBoot實現動態定時任務

項目情況:

         在當前項目中需要一個定時任務來清除過期的校驗碼,如果使用數據庫存儲過程的話不方便維護。因此採用SpringBoot自帶的方式來設置定時任務。

技術說明:

         SpringBoot自帶的方式有兩種可以實現:

        一種是使用@Scheduled註解的方式,只需要在啓動類或者它所在的類上添加@EnableScheduling註解允許執行定時任務,並且設置Schecduled註解的參數,諸如:

        1.cron是設置定時執行的表達式,如 0 0/5 * * * ?每隔五分鐘執行一次

        2.zone表示執行時間的時區

        3.fixedDelay 和fixedDelayString 表示一個固定延遲時間執行,上個任務完成後,延遲多長時間執行

        4.fixedRate 和fixedRateString表示一個固定頻率執行,上個任務開始後,多長時間後開始執行

        5.initialDelay 和initialDelayString表示一個初始延遲時間,第一次被調用前延遲的時間

    示例代碼如下:

package com.allcom.service;

import com.allcom.dao.MysqlDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

/**
* @Author: zy
* @Description: 定時任務
* @Date: 2018/7/12_15:15
**/
@Service
public class TaskService {

    @Autowired
    private MysqlDao mysqlDao;

    @Scheduled(fixedRate = 5*1000)
    public void deleteInvalidCheckCode() {
        mysqlDao.deleteInvalidCheckCode();
    }


}

         另一種方式是通過自定義配置類的方式,步驟如下:

         第一步:新建一個類實現SchedulingConfigurer接口,並添加@Configuration註解,@EnableScheduling註解可以寫在這裏也可以寫在啓動類上,這裏我寫在了啓動類上。

   

          第二步: 重寫configureTasks方法如下代碼所示:

package com.allcom.task;

import com.allcom.service.TaskService;
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.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;



import java.util.Date;


@Configuration
public class MyScheduledTask implements SchedulingConfigurer {

    @Mapper
    public interface CronMapper {
        @Select("select cron from user_cron limit 1")
        String getCron();
    }

    @Autowired
    @SuppressWarnings("all")
    CronMapper cronMapper;


    @Autowired
    @SuppressWarnings("all")
    private TaskService taskService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
           scheduledTaskRegistrar.addTriggerTask(new Runnable() {
               @Override
               public void run() {
                   try {
                       taskService.deleteInvalidCheckCode();  //異步定時操作
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }
           }, new Trigger() {
               @Override
               public Date nextExecutionTime(TriggerContext triggerContext) {
                   String cron =cronMapper.getCron();
                    if("".equals(cron)||cron==null)
                        return null;
                   //定時任務觸發,可修改定時任務的執行週期
                   CronTrigger trigger=new CronTrigger(cron);
                   Date nextExecDate= trigger.nextExecutionTime(triggerContext);
                   return nextExecDate;
               }
           });
    }
}

              第三步:啓動項目,定時任務就自動添加了。

   注意:這裏我使用的是@Mapper註解使用Mybatis寫了一個獲取cron表達式的接口,可以從數據庫中查詢自定義表的cron字段值。這樣的話項目運行的過程中,不用重新啓動項目,只需要修改數據庫中的字段值就可以動態的修改定時任務中的cron值,實現動態修改定時任務執行時間的功能。

          但是,這種方式有一個缺點就是,將數據庫cron字段值設爲null或者“”以及不正確的值,這樣定時任務就會停止執行,這樣就算你下一次再給cron字段添加了正確的值,項目也不會執行定時任務了,這個時候就需要重新啓動數據庫才行。

          這種方式適合於前臺給幾個特定的值給用戶選擇,不能讓用戶隨便填。

附定時任務執行內容:

/**
* @Author: zy
* @Description: 刪除用戶過期的校驗碼
* @Date: 2018/7/12_15:20
**/
@Delete("DELETE from registinfo where id in (select id from (SELECT id FROM registinfo WHERE TIMESTAMPDIFF(MINUTE,lastupdatetime,NOW()) >= 15)a )")
void deleteInvalidCheckCode();

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章