springboot quartz 动态配置_springboot集成quartz实现动态任务调度
quartz是一個開源的作業(yè)調(diào)度框架,本文就是介紹下springboot框架下繼承quartz的一些使用示例
首先我們需要添加quartz的spring-boot-starter-quartz依賴
org.springframework.bootspring-boot-starter-quartz我們需要做一些配置。quartz提供了基于內(nèi)存(MEMORY)和基于jdbc的兩種任務存儲方式。具體的配置可參考下面的示例
spring: quartz: jdbc: initialize-schema: never job-store-type: JDBC properties: org: quartz: scheduler: instanceName: myQuartzCluster instanceId: AUTO jobstore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix: qrtz_ isClustered: true clusterCheckinInterval: 10000 useProperties: false threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 5 threadPriority: 5 threadsInheritContextClassLoaderOfInitializingThread: true需要注意的是,如果是集群部署而且定時任務同時只能一個實例運行的話,需要配置成jdbc方式,這樣就可以用到數(shù)據(jù)庫的鎖。MEMORY這種方式建議用于開發(fā)環(huán)境測試,不建議用于生產(chǎn)環(huán)境。
如果是使用jdbc的方式,quartz提供了不同數(shù)據(jù)庫的建表語句。可以在quartz的jar包中找到
具體路徑是org.quartz.impl.jdbcjobstore
定時任務的類需要繼承自QuartzJobBean并重寫 executeInternal方法。
package com.xchaset.quartz.schedule.task;import com.xchaset.quartz.annotation.MyScheduled;import lombok.extern.slf4j.Slf4j;import org.quartz.DisallowConcurrentExecution;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;import org.springframework.stereotype.Service;@Service@Slf4j@DisallowConcurrentExecution@MyScheduled(name = "EmailTask",description = "email schedule task",cronExpression = "0 0/2 * * * ?")public class EmailTask extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("{} is execute!",this.getClass().getSimpleName()); }}@DisallowConcurrentExecution注解可以控制我們的相同類的定時任務同時只有一個執(zhí)行。通常的場景是如果定時任務實際執(zhí)行時間大于設定的定時任務執(zhí)行間隔時間,就會導致同時多個任務并行。
@MyScheduled是自定義的一個注解,主要用于應用啟動時將定時任務注冊。
package com.xchaset.quartz.annotation;import org.springframework.stereotype.Service;import java.lang.annotation.*;@Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Servicepublic @interface MyScheduled { String name() default ""; String description() default ""; String cronExpression() default ""; boolean enable() default true;}獲取注解類上的信息
package com.xchaset.quartz.utils;import com.xchaset.quartz.annotation.MyScheduled;import com.xchaset.quartz.schedule.JobBean;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.scheduling.quartz.QuartzJobBean;import java.util.ArrayList;import java.util.List;import java.util.Map;public class MyAnnotationUtil { public static List getAllMyScheduledTask(){ List jobBeans = new ArrayList<>(); Map beansOfType = SpringContextHolder.getBeansOfType(QuartzJobBean.class); for (Map.Entry beanEntry : beansOfType.entrySet()) { MyScheduled annotation = AnnotationUtils.findAnnotation(beanEntry.getValue().getClass(), MyScheduled.class); QuartzJobBean value = beanEntry.getValue(); if (annotation == null) { continue; } if (annotation.enable()) { String name = annotation.name(); String description = annotation.description(); String cronExpression = annotation.cronExpression(); JobBean build = JobBean.builder().jobName(name) .groupName("myGroup") .cronExpression(cronExpression) .description(description) .quartzJobBean(value.getClass()) .build(); jobBeans.add(build); } } return jobBeans; }}啟動時注冊任務
package com.xchaset.quartz.schedule;import com.xchaset.quartz.utils.MyAnnotationUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;import java.util.List;@Componentpublic class ScheduleCommandLine implements CommandLineRunner { @Autowired private QuartzService quartzService; @Override public void run(String... args) throws Exception { List allMyScheduledTask = MyAnnotationUtil.getAllMyScheduledTask(); for (JobBean jobBean : allMyScheduledTask) { quartzService.deleteJob(jobBean.getGroupName(),jobBean.getJobName()); quartzService.addJob(jobBean.getQuartzJobBean(),jobBean.getGroupName(),jobBean.getJobName(),jobBean.getCronExpression(),null); } }}對于怎么做到動態(tài)的添加、暫停、刪除、恢復、執(zhí)行一個任務呢? quartz提供了這樣的API。我們只需要稍微做一下封裝。以接口的形式提供出去就可以了。
package com.xchaset.quartz.schedule;import org.quartz.*;import org.quartz.impl.matchers.GroupMatcher;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.quartz.QuartzJobBean;import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;import java.util.*;@Servicepublic class QuartzService { @Autowired private Scheduler scheduler; @PostConstruct public void startScheduler() { try { scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } /** * 添加一個任務 * @param jobClass * @param jobGroup * @param jobName * @param jobTime * @param jobMap * @throws SchedulerException */ public void addJob(Class extends QuartzJobBean> jobClass, String jobGroup, String jobName, String jobTime, Map jobMap) throws SchedulerException { JobDetail build = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build(); if (jobMap != null && jobMap.size() > 0) { build.getJobDataMap().putAll(jobMap); } Trigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup) .startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND)) .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build(); scheduler.scheduleJob(build, cronTrigger); } /** * 更新任務時間表達式 * @param jobGroup * @param jobName * @param jobTime * @throws SchedulerException */ public void updateJob(String jobGroup, String jobName, String jobTime) throws SchedulerException { TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); CronTrigger trigger = (CronTrigger)scheduler.getTrigger(triggerKey); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build(); scheduler.rescheduleJob(triggerKey,trigger); } /** * 刪除任務 * @param jobGroup * @param jobName * @throws SchedulerException */ public void deleteJob(String jobGroup,String jobName) throws SchedulerException { scheduler.deleteJob(new JobKey(jobName,jobGroup)); } public void pauseJob(String jobGroup,String jobName) throws SchedulerException { scheduler.pauseJob(new JobKey(jobName,jobGroup)); } /** * 恢復任務 * @param jobGroup * @param jobName * @throws SchedulerException */ public void resumeJob(String jobGroup,String jobName) throws SchedulerException { scheduler.resumeJob(new JobKey(jobName,jobGroup)); } /** * 立刻執(zhí)行一個任務 * @param jobGroup * @param jobName * @throws SchedulerException */ public void runAJobNow(String jobGroup,String jobName) throws SchedulerException { scheduler.triggerJob(new JobKey(jobName,jobGroup)); } /** * 查詢所有的任務 * @return * @throws SchedulerException */ public List queryAllJob() throws SchedulerException { GroupMatcher anyJobGroup = GroupMatcher.anyJobGroup(); Set jobKeys = scheduler.getJobKeys(anyJobGroup); List result = getJobDetailsBeans(jobKeys); return result; } private List getJobDetailsBeans(Collection jobKeys) throws SchedulerException { List result = new ArrayList<>(); for (JobKey jobKey : jobKeys) { List extends Trigger> triggersOfJob = scheduler.getTriggersOfJob(jobKey); for (Trigger trigger : triggersOfJob) { String group = jobKey.getGroup(); String name = jobKey.getName(); String className = jobKey.getClass().getName(); String description = trigger.getDescription(); JobDataMap jobDataMap = trigger.getJobDataMap(); Date nextFireTime = trigger.getNextFireTime(); Date previousFireTime = trigger.getPreviousFireTime(); Trigger.TriggerState triggerState = scheduler.getTriggerState(TriggerKey.triggerKey(name, group)); String cronExpression = ""; if (trigger instanceof CronTrigger) { cronExpression = ((CronTrigger) trigger).getCronExpression(); } JobDetailsBean build = JobDetailsBean.builder().className(className).groupName(group).jobName(name).description(description) .cronExpression(cronExpression).jobDataMap(jobDataMap).nextFireTime(nextFireTime).previousFireTime(previousFireTime) .triggerState(triggerState.name()).build(); result.add(build); } } return result; } /** * 查詢正在執(zhí)行的任務 * @return * @throws SchedulerException */ public List queryCurrentExecutingJob() throws SchedulerException { List result = new ArrayList<>(); List currentlyExecutingJobs = scheduler.getCurrentlyExecutingJobs(); for (JobExecutionContext currentlyExecutingJob : currentlyExecutingJobs) { Trigger trigger = currentlyExecutingJob.getTrigger(); JobDataMap jobDataMap = trigger.getJobDataMap(); JobKey jobKey = trigger.getJobKey(); String group = jobKey.getGroup(); String name = jobKey.getName(); String className = jobKey.getClass().getName(); Date nextFireTime = trigger.getNextFireTime(); String description = trigger.getDescription(); Date previousFireTime = trigger.getPreviousFireTime(); Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); String cronExpression = ""; if (trigger instanceof CronTrigger) { cronExpression = ((CronTrigger) trigger).getCronExpression(); } JobDetailsBean build = JobDetailsBean.builder().className(className).groupName(group).jobName(name).description(description) .cronExpression(cronExpression).jobDataMap(jobDataMap).nextFireTime(nextFireTime).previousFireTime(previousFireTime) .triggerState(triggerState.name()).build(); result.add(build); } return result; }}我們可以在上面代碼的基礎上,對外提供接口,這樣就可以通過可視化的界面來動態(tài)的對任務進行調(diào)度了。
以上就是springboot集成quartz的簡單使用了。
總結(jié)
以上是生活随笔為你收集整理的springboot quartz 动态配置_springboot集成quartz实现动态任务调度的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AMD悄悄公布31个CPU漏洞:4个极危
- 下一篇: 再添新航点:国产大飞机 C919 飞抵青