springboot定時任務—實現SchedulingConfigurer介面做定時排程(一)
阿新 • • 發佈:2021-01-17
技術標籤:springSchedulConfig配置表實現定時任務springboot定時任務讓定時任務實現視覺化SchedulingConf
定時任務在平時的工作中是很常見的,怎麼有效的管理這些個定時任務呢?有的用配置檔案,而我卻喜歡用視覺化列表管理,其實原理也就是把所有的定時任務都放到表裡去管理,在專案啟動的時候把這些個定時任務掃描到定時任務裡即可!廢話不多說了,先看看怎麼去實現吧。其實SchedulingConfigurer實現方法很簡單,只需要實現SchedulingConfigurer並重寫configureTasks方法,在啟動類必須加上@EnableScheduling註解 即可。這裡我就是做個封裝和優化,讓定時任務更好管理,原理還是這個原理。整個專案的實現是在springboot+jpa的環境下。跟著下面的嚮導來學習吧:
目錄
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秒觸發任務
好了,到這裡整個定時任務的功能就完成了,以後只需要再定時任務表裡新增相應的類和方法,就能把自動的開啟這個定時任務!讓定時任務更簡單!!!大家可以去試試,上面的程式碼都是親自測試過的,沒有任何問題的!