SpringBoot實(shí)現(xiàn)quartz定時(shí)任務(wù)可視化管理功能
前言
在實(shí)際框架或產(chǎn)品開發(fā)過程中,springboot中集成quarzt方式基本是以job和trigger的bean對(duì)象方式直接硬編碼完成的,例如以下代碼示例。對(duì)于系統(tǒng)內(nèi)定義的所有定時(shí)任務(wù)類型,具體執(zhí)行類,執(zhí)行策略,運(yùn)行狀態(tài)都沒有一個(gè)動(dòng)態(tài)全局的管理,所有決定將quartz做成可視化配置管理,便于統(tǒng)一管理,也降低了使用門檻,只需要關(guān)心job類的實(shí)現(xiàn)即可
@Bean public JobDetail SMSJobDetail() { return JobBuilder.newJob(SMSJob.class).withIdentity("SMSJob").storeDurably().build(); } // 把jobDetail注冊(cè)到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)
用于存儲(chǔ)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表達(dá)式任務(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, "時(shí)"); 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入對(duì)象
@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); // 進(jìn)行注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
QuartzConfig
注入QuartzFactory對(duì)象
@Configuration public class QuartzConfig { @Autowired private QuartzFactory quartzFactory; @Bean public SchedulerFactoryBean schedulerFactoryBean(){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(quartzFactory); //將job實(shí)例化,能夠操作進(jìn)行Spring 注入 return schedulerFactoryBean; } }
QuartzUtil
定時(shí)任務(wù)動(dòng)態(tài)添加/刪除操作類,initQuartzTask方法在系統(tǒng)啟動(dòng)時(shí)執(zhí)行,根據(jù)配置自動(dòng)開啟相關(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定時(shí)任務(wù)成功,任務(wù)數(shù)量:" + openTaskList.size() + "個(gè)"); } } 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(); } } //增加定時(shí)任務(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(); // 啟動(dòng) } } catch (Exception e) { throw new RuntimeException(e); } } //增加corn表達(dá)式任務(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(); // 啟動(dòng) } } 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實(shí)現(xiàn)quartz定時(shí)任務(wù)可視化管理的文章就介紹到這了,更多相關(guān)SpringBoot 定時(shí)任務(wù)可視化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot實(shí)現(xiàn)定時(shí)任務(wù)動(dòng)態(tài)管理示例
- Springboot-admin整合Quartz實(shí)現(xiàn)動(dòng)態(tài)管理定時(shí)任務(wù)的過程詳解
- SpringBoot日程管理Quartz與定時(shí)任務(wù)Task實(shí)現(xiàn)詳解
- SpringBoot中使用Quartz管理定時(shí)任務(wù)的方法
- SpringBoot基于數(shù)據(jù)庫的定時(shí)任務(wù)統(tǒng)一管理的實(shí)現(xiàn)
- Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)管理的示例代碼
相關(guān)文章
舉例講解Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制
這篇文章主要介紹了Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制,包括泛化的Class引用以及類型檢查instanceof等知識(shí)點(diǎn),需要的朋友可以參考下2016-05-05Mybatis Plus 代碼生成器的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis Plus 代碼生成器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03SpringBoot中yml的數(shù)據(jù)綁定示例
本文主要介紹了SpringBoot中yml的數(shù)據(jù)綁定示例,借助于YAML的簡潔語法和結(jié)構(gòu)化特性,我們能夠輕松地管理應(yīng)用程序的配置信息,使得配置文件更加清晰易讀,感興趣的可以了解一下2023-11-11springboot加載復(fù)雜的yml文件獲取不到值的解決方案
這篇文章主要介紹了springboot加載復(fù)雜的yml文件獲取不到值的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)詳解流程
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用
這篇文章主要介紹了 log4j.properties配置與加載應(yīng)用的相關(guān)資料,需要的朋友可以參考下2018-02-02