SpringBoot實現(xiàn)quartz定時任務(wù)可視化管理功能
前言
在實際框架或產(chǎn)品開發(fā)過程中,springboot中集成quarzt方式基本是以job和trigger的bean對象方式直接硬編碼完成的,例如以下代碼示例。對于系統(tǒng)內(nèi)定義的所有定時任務(wù)類型,具體執(zhí)行類,執(zhí)行策略,運行狀態(tài)都沒有一個動態(tài)全局的管理,所有決定將quartz做成可視化配置管理,便于統(tǒng)一管理,也降低了使用門檻,只需要關(guān)心job類的實現(xiàn)即可
@Bean
public JobDetail SMSJobDetail() {
return JobBuilder.newJob(SMSJob.class).withIdentity("SMSJob").storeDurably().build();
}
// 把jobDetail注冊到trigger上去
@Bean
public Trigger myJobTrigger() {
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(1).repeatForever();
return TriggerBuilder.newTrigger()
.forJob(SMSJobDetail())
.withIdentity("myJobTrigger")
.withSchedule(scheduleBuilder)
.build();
}
表結(jié)構(gòu)
用于存儲quartz配置
DROP TABLE IF EXISTS `f_quartztask`; CREATE TABLE `f_quartztask` ( `TaskID` varchar(50) NOT NULL, `TaskName` varchar(200) DEFAULT NULL, `TaskType` int(11) DEFAULT NULL, `TaskTag` varchar(100) DEFAULT NULL, `JobClassPath` varchar(200) DEFAULT NULL, `ExecutePeroid` int(11) DEFAULT NULL, `ExecuteUnit` int(11) DEFAULT NULL, `CornExpress` varchar(200) DEFAULT NULL, `Enviroment` varchar(50) DEFAULT NULL, `TaskStatus` int(11) DEFAULT NULL, `SortNum` int(11) DEFAULT NULL, `Remark` varchar(500) DEFAULT NULL, PRIMARY KEY (`TaskID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
枚舉類
public class QuartzEnum {
public enum TaskType implements IConvertEnumToCodeItem {
Cycle(10, "循環(huán)任務(wù)"), Corn(20, "Corn表達式任務(wù)");
private int _value;
private String _name;
private TaskType(int value, String name) {
set_value(value);
set_name((name));
}
public int get_value() {
return _value;
}
public void set_value(int _value) {
this._value = _value;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
@Override
public String toString() {
return _name;
}
@Override
public String getCodeName() {
return "Quartz任務(wù)類別";
}
}
public enum ExecuteUnit implements IConvertEnumToCodeItem {
Second(10, "秒"), Minute(20, "分"), Hour(30, "時");
private int _value;
private String _name;
private ExecuteUnit(int value, String name) {
set_value(value);
set_name((name));
}
public int get_value() {
return _value;
}
public void set_value(int _value) {
this._value = _value;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
@Override
public String toString() {
return _name;
}
@Override
public String getCodeName() {
return "Quartz間隔單位";
}
}
public enum TaskStatus implements IConvertEnumToCodeItem {
Open(10, "開啟"), Close(20, "關(guān)閉");
private int _value;
private String _name;
private TaskStatus(int value, String name) {
set_value(value);
set_name((name));
}
public int get_value() {
return _value;
}
public void set_value(int _value) {
this._value = _value;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
@Override
public String toString() {
return _name;
}
@Override
public String getCodeName() {
return "Quartz任務(wù)狀態(tài)";
}
}
public enum TaskEnviroment implements IConvertEnumToCodeItem {
All("全部", "全部"), Dev("dev", "開發(fā)環(huán)境"), Pro("pro", "正式環(huán)境");
private String _value;
private String _name;
private TaskEnviroment(String value, String name) {
set_value(value);
set_name((name));
}
public String get_value() {
return _value;
}
public void set_value(String _value) {
this._value = _value;
}
public String get_name() {
return _name;
}
public void set_name(String _name) {
this._name = _name;
}
@Override
public String toString() {
return _name;
}
@Override
public String getCodeName() {
return "Quartz任務(wù)執(zhí)行環(huán)境";
}
}
}
QuartzFactory
支持Job類注bean入對象
@Component
public class QuartzFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 調(diào)用父類的方法
Object jobInstance = super.createJobInstance(bundle);
// 進行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
QuartzConfig
注入QuartzFactory對象
@Configuration
public class QuartzConfig {
@Autowired
private QuartzFactory quartzFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(quartzFactory);
//將job實例化,能夠操作進行Spring 注入
return schedulerFactoryBean;
}
}
QuartzUtil
定時任務(wù)動態(tài)添加/刪除操作類,initQuartzTask方法在系統(tǒng)啟動時執(zhí)行,根據(jù)配置自動開啟相關(guān)符合條件的任務(wù)
@Component
public class QuartzUtil {
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@Autowired
private F_QuartzTaskService quartzTaskService;
@Value("${spring.profiles.active}")
private String active;
private static String JOB_GROUP_NAME = "DEFAULT_JOB_GROUP_NAME";
private static String TRIGGER_GROUP_NAME = "DEFAULT_TRIGGER_GROUP_NAME";
public void initQuartzTask() {
List<F_QuartzTaskDO> openTaskList = quartzTaskService.selectAllList();
if(openTaskList.size()>0){
openTaskList = openTaskList.stream().filter(a -> a.getTaskStatus() == QuartzEnum.TaskStatus.Open.get_value() &&
(a.getEnviroment().equals(QuartzEnum.TaskEnviroment.All.get_name()) || a.getEnviroment().equals(active))).collect(Collectors.toList());
}
for (F_QuartzTaskDO taskDO : openTaskList) {
try {
Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());
if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {
addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());
} else {
addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (openTaskList.size() > 0) {
System.out.println("掃描并初始化開啟quartz定時任務(wù)成功,任務(wù)數(shù)量:" + openTaskList.size() + "個");
}
}
public void startTask( F_QuartzTaskDO taskDO){
try {
Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());
if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {
addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());
} else {
addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());
}
} catch (Exception e) {
e.printStackTrace();
}
}
//增加定時任務(wù)任務(wù)
public void addIntervalJob(String jobName, Class<? extends Job> cls, int peroid, int timeUnit) {
try {
SimpleScheduleBuilder scheduleBuilder = null;
if (timeUnit == QuartzEnum.ExecuteUnit.Second.get_value()) {
scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(peroid).repeatForever();
} else if (timeUnit == QuartzEnum.ExecuteUnit.Minute.get_value()) {
scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(peroid).repeatForever();
} else if (timeUnit == QuartzEnum.ExecuteUnit.Hour.get_value()) {
scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInHours(peroid).repeatForever();
}
Scheduler sched = schedulerFactoryBean.getScheduler();
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).storeDurably().build();
Trigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail).withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(scheduleBuilder).build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 啟動
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//增加corn表達式任務(wù)
public void addCornJob(String jobName, Class<? extends Job> cls, String cornExpress) {
try {
Scheduler sched = schedulerFactoryBean.getScheduler();
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
CronTrigger trigger = (CronTrigger) TriggerBuilder
.newTrigger()
.withIdentity(jobName, TRIGGER_GROUP_NAME)
.withSchedule(CronScheduleBuilder.cronSchedule(cornExpress))
.build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start(); // 啟動
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//停止任務(wù)
public void deleteJob(String jobName) {
try {
Scheduler sched = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
sched.pauseTrigger(triggerKey); // 停止觸發(fā)器
sched.unscheduleJob(triggerKey);// 移除觸發(fā)器
sched.deleteJob(jobKey); // 刪除任務(wù)
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
界面展示


到此這篇關(guān)于SpringBoot實現(xiàn)quartz定時任務(wù)可視化管理的文章就介紹到這了,更多相關(guān)SpringBoot 定時任務(wù)可視化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中yml的數(shù)據(jù)綁定示例
本文主要介紹了SpringBoot中yml的數(shù)據(jù)綁定示例,借助于YAML的簡潔語法和結(jié)構(gòu)化特性,我們能夠輕松地管理應(yīng)用程序的配置信息,使得配置文件更加清晰易讀,感興趣的可以了解一下2023-11-11
springboot加載復(fù)雜的yml文件獲取不到值的解決方案
這篇文章主要介紹了springboot加載復(fù)雜的yml文件獲取不到值的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Java實現(xiàn)學(xué)生管理系統(tǒng)詳解流程
這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-06-06
詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用
這篇文章主要介紹了 log4j.properties配置與加載應(yīng)用的相關(guān)資料,需要的朋友可以參考下2018-02-02

