1. 程式人生 > 其它 >springboot定時任務—實現SchedulingConfigurer介面做定時排程(一)

springboot定時任務—實現SchedulingConfigurer介面做定時排程(一)

技術標籤:springSchedulConfig配置表實現定時任務springboot定時任務讓定時任務實現視覺化SchedulingConf

定時任務在平時的工作中是很常見的,怎麼有效的管理這些個定時任務呢?有的用配置檔案,而我卻喜歡用視覺化列表管理,其實原理也就是把所有的定時任務都放到表裡去管理,在專案啟動的時候把這些個定時任務掃描到定時任務裡即可!廢話不多說了,先看看怎麼去實現吧。其實SchedulingConfigurer實現方法很簡單,只需要實現SchedulingConfigurer並重寫configureTasks方法,在啟動類必須加上@EnableScheduling註解

即可。這裡我就是做個封裝和優化,讓定時任務更好管理,原理還是這個原理。整個專案的實現是在springboot+jpa的環境下。跟著下面的嚮導來學習吧:

目錄

1.建立定時任務的管理表(sys_scheduled)

2.構造定時任務表的相關類

2.1 實體類

2.2 Repository資料庫互動類

2.3 Service服務類

3.定時任務配置類(這個是重點哦!!!!)

3.1主要是為了獲取bean

3.2配置類和定時任務管理表的互動(建立關係)

4.測試類編寫並進行驗證

5.奉上一些常用的cron表示式


1.建立定時任務的管理表(sys_scheduled)

CREATE TABLE `sys_scheduled` (
  `id` varchar(32) NOT NULL COMMENT '主鍵',
  `job_name` varchar(200) DEFAULT NULL COMMENT '定時任務名稱',
  `class_name` varchar(200) DEFAULT NULL COMMENT '類名',
  `method` varchar(250) DEFAULT NULL COMMENT '方法名',
  `cron` varchar(200) DEFAULT NULL COMMENT '定時任務表示式',
  `start_flag` varchar(2) DEFAULT NULL COMMENT '啟用標記',
  `create_date` varchar(32) DEFAULT NULL COMMENT '建立日期',
  `create_by` varchar(32) DEFAULT NULL COMMENT '建立人',
  `update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
  `update_date` varchar(32) DEFAULT NULL COMMENT '更新日期',
  `del_flag` varchar(32) DEFAULT NULL COMMENT '刪除標記',
  `temp1` varchar(2500) DEFAULT NULL COMMENT '備註',
  `temp2` varchar(64) DEFAULT NULL COMMENT '備用欄位2',
  `temp3` varchar(250) DEFAULT NULL COMMENT '備用欄位3',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='定時任務配置表';

2.構造定時任務表的相關類

2.1 實體類

package com.lengmo.entity;

import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;

@Entity
@Data//讓實體類的get和set方法得以簡化,引入lombok包即可
@Table(name="sys_scheduled")
public class SysScheduled  implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private String id;		// 主鍵
	@Column(name="job_name")//表裡的欄位名稱對映到實體類
	private String jobName;		// 定時任務名稱
	@Column(name="class_name")
	private String className;		// 類名
	@Column(name="method")
	private String method;		// 方法名
	@Column(name="cron")
	private String cron;		// 定時任務表示式
	@Column(name="start_flag")
	private String startFlag;		// 啟用標記
	@Column(name="temp1")
	private String temp1;//備註
}

2.2 Repository資料庫互動類

package com.lengmo.repository;

import com.lengmo.entity.SysScheduled;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.io.Serializable;
import java.util.List;

public interface SysScheduledRepository extends JpaRepository<SysScheduled, Serializable> {
    @Query(" from SysScheduled s where s.startFlag='1'")
    public List<SysScheduled> getScheduleList();
}

2.3 Service服務類

package com.lengmo.service;

import java.util.List;
import com.lengmo.entity.SysScheduled;
import com.lengmo.repository.SysScheduledRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SysScheduledService{
	@Autowired
	private SysScheduledRepository sysScheduledRepository;
	public List<SysScheduled>  getScheduleList(){
		return sysScheduledRepository.getScheduleList();
	}		
}

3.定時任務配置類(這個是重點哦!!!!)

3.1主要是為了獲取bean

package com.lengmo.common;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
@Lazy(false)
public class ApplicationContextHelper implements ApplicationContextAware {
 
    private static ApplicationContext applicationContext;
 
    public ApplicationContextHelper() {
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHelper.applicationContext = applicationContext;
    }
 
    public static Object getBean(String beanName) {
       return applicationContext != null?applicationContext.getBean(beanName):null;
    }
}

3.2配置類和定時任務管理表的互動(建立關係)

package com.lengmo.common;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import com.lengmo.entity.SysScheduled;
import com.lengmo.service.SysScheduledService;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

@Component
public class ScheduleSetting implements SchedulingConfigurer {
    @Autowired
    private SysScheduledService sysScheduledService;
 
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        // 獲取所有任務
    	List<SysScheduled> scheduleList = sysScheduledService.getScheduleList();
    	System.out.println(scheduleList.size());
         for (SysScheduled s : scheduleList){
             scheduledTaskRegistrar.addTriggerTask(getRunnable(s), getTrigger(s));
         }
    }
 
 
    /**
     * 轉換首字母小寫
     *
     * @param str
     * @return
     */
    public static String lowerFirstCapse(String str) {
        char[] chars = str.toCharArray();
        chars[0] += 32;
        return String.valueOf(chars);
    }
 
    /**
     * runnable
     * @param scheduleConfig
     * @return
     */
    private Runnable getRunnable(final SysScheduled scheduleConfig){
        return new Runnable() {
            @Override
            public void run() {
                Class<?> clazz;
                try {
                    clazz = Class.forName(scheduleConfig.getClassName());
                    String className = lowerFirstCapse(clazz.getSimpleName());
                    Object bean = (Object) ApplicationContextHelper.getBean(className);
                    Method method = ReflectionUtils.findMethod(bean.getClass(), scheduleConfig.getMethod());
                    ReflectionUtils.invokeMethod(method, bean);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        };
    }
 
    /**
     * Trigger
     * @param scheduleConfig
     * @return
     */
    private Trigger getTrigger(final SysScheduled scheduleConfig){
        return new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                CronTrigger trigger = new CronTrigger(scheduleConfig.getCron());
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        };
 
    }
}

4.測試類編寫並進行驗證

package com.lengmo.common.scheduled;

import org.springframework.stereotype.Component;

@Component
public class TaskTest1 {
    public  void runTaskTest(){
        System.out.println("=====================測試定時任務====================");
    }
}

5.奉上一些常用的cron表示式

Cron表示式: *秒 *分鐘 *小時 *天 *月 *星期 *年份
0~59 0~59 0~23 0~31 0~11 1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT 1970-2099

“30 * * * * ?”不是每30秒執行一次的意思,這個是每分鐘的第30秒執行的意思

#經典案例: 
“30 * * * * ?” 每分鐘第30秒觸發任務
“30 10 * * * ?” 每小時的10分30秒觸發任務 
“30 10 1 * * ?” 每天1點10分30秒觸發任務 
“30 10 1 20 * ?” 每月20號1點10分30秒觸發任務 
“30 10 1 20 10 ? *” 每年10月20號1點10分30秒觸發任務 
“30 10 1 20 10 ? 2011” 2011年10月20號1點10分30秒觸發任務 
“30 10 1 ? 10 * 2011” 2011年10月每天1點10分30秒觸發任務 
“30 10 1 ? 10 SUN 2011” 2011年10月每週日1點10分30秒觸發任務 
“15,30,45 * * * * ?” 每分鐘的第15秒,30秒,45秒時觸發任務 
“15-45 * * * * ?” 15到45秒內,每秒都觸發任務 
“15/5 * * * * ?” 每分鐘的每15秒開始觸發,每隔5秒觸發一次 
“15-30/5 * * * * ?” 每分鐘的15秒到30秒之間開始觸發,每隔5秒觸發一次 
“0 0/3 * * * ?” 每小時的第0分0秒開始,每三分鐘觸發一次 
“0 15 10 ? * MON-FRI” 星期一到星期五的10點15分0秒觸發任務 
“0 15 10 L * ?” 每個月最後一天的10點15分0秒觸發任務 
“0 15 10 LW * ?” 每個月最後一個工作日的10點15分0秒觸發任務 
“0 15 10 ? * 5L” 每個月最後一個星期四的10點15分0秒觸發任務 
“0 15 10 ? * 5#3”每個月第三週的星期四的10點15分0秒觸發任務

好了,到這裡整個定時任務的功能就完成了,以後只需要再定時任務表裡新增相應的類和方法,就能把自動的開啟這個定時任務!讓定時任務更簡單!!!大家可以去試試,上面的程式碼都是親自測試過的,沒有任何問題的!