记录自己学习的理解,以供日后查阅,欢迎指正不对之处!
实现Job接口,通过execute(JobExecutionContext context)方法定义定时任务具体干些什么。
为job添加相关信息,如Job 名字、描述、关联监听器、存入任务对应参数等信息,我们可以通过这些信息查找和操作定时任务,以及定时任务在执行时通过上下文获取参数信息。每个JobDetail的组和名称必须唯一。
定义触发器名、触发器组、设定触发时间等信息。告诉调度器何时执行定时任务。每个Trigger的组和名称必须唯一。
调度器,相当于一个容器装载着JobDetail和Trigger。定义了JobDetail和Trigger的对应关系。我们可以通过组和名称访问容器中 Trigger 和 JobDetail。
相互之间的关系:一个Job可以对应多个JobDetail,一个JobDetail可以对应多个Trigger,而一个Trigger只能对应一个JobDetail,一个Scheduler可以注册多个JobDetail和多个Trigger。
实现QuartzJobBean自定义job,executeInternal方法定义job具体执行的细节。
@Data public class SampleJob extends QuartzJobBean { private String name; @Override protected void executeInternal(JobExecutionContext context) { System.out.println(String.format("sampleJob name:%s !",this.name)); } }withIdentity:方法定义名称和组。只传一个参数时代表组名,名称自动生成。 usingJobData:方法表示设置job的参数。 storeDurably:表示持久化信息。 withIntervalInSeconds:方法表示设置多少秒执行。 repeatForever():方法表示一直重复执行。 withSchedule:注册的容器类型。
@Configuration public class SampleScheduler { @Bean public JobDetail sampleJobDetail(){ return JobBuilder.newJob(SampleJob.class) .withIdentity("SampleJobDetail") .usingJobData("name", "Hello sample job!") .storeDurably() .build(); } @Bean public Trigger sampleJobTrigger(){ SimpleScheduleBuilder builder = SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(2) .repeatForever(); return TriggerBuilder.newTrigger() .forJob(sampleJobDetail()) .withIdentity("sampleTrigger") .withSchedule(builder) .build(); } }实现定时任务的实时查询、修改、新增、删除功能
@Component public class QuartzManager { //任务组名 private static final String JOB_GROUP_NAME = "cron_group"; //触发器组名 private static final String TRIGGER_GROUP_NAME = "cron_trigger"; //调度工厂 @Autowired private SchedulerFactoryBean schedulerFactory; public Scheduler getScheduled(){ return schedulerFactory.getScheduler(); } /** * 添加定时任务 * @param jobName 任务名称 * @param jobClazz 任务job * @param cron 执行时间之cron表达式 * @param params 任务job参数 */ public void addJob(String jobName , Class jobClazz , String cron, HashMap<String,String> params){ try { //获取Scheduler Scheduler scheduler = getScheduled(); // 任务名,任务组,任务执行类 JobDetail jobDetail= JobBuilder.newJob(jobClazz).withIdentity(jobName, JOB_GROUP_NAME).build(); // 传参(可选) JobDataMap jobDataMap = jobDetail.getJobDataMap(); if(params != null ){ for (String key:params.keySet()){ jobDataMap.put(key, params.get(key)); } } // 触发器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(jobName, TRIGGER_GROUP_NAME); triggerBuilder.startNow(); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 创建Trigger对象 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); // 调度容器设置JobDetail和Trigger scheduler.scheduleJob(jobDetail, trigger); // 启动 if (!scheduler.isShutdown()) { scheduler.start(); } } catch (SchedulerException e) { e.printStackTrace(); } } /** * 删除定时任务 * @param jobName 任务名称 */ public void removeJob(String jobName) { try { Scheduler scheduler = getScheduled(); TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME); scheduler.pauseTrigger(triggerKey);// 停止触发器 scheduler.unscheduleJob(triggerKey);// 移除触发器 scheduler.deleteJob(JobKey.jobKey(jobName, JOB_GROUP_NAME));// 删除任务 } catch (SchedulerException e) { e.printStackTrace(); } } /** * 启动任务 */ public void startJobs() { try { Scheduler scheduler = getScheduled(); scheduler.start(); } catch (SchedulerException e) { e.printStackTrace(); } } /** * 删除任务 */ public void shutdownJobs() { try { Scheduler scheduler = getScheduled(); if (!scheduler.isShutdown()) { scheduler.shutdown(); } } catch (SchedulerException e) { e.printStackTrace(); } } /** * 获取所有任务 */ public List<String> getAllJob(){ List<String> jobs = new ArrayList<>(); try { Set<JobKey> jobKeys = getScheduled().getJobKeys(GroupMatcher.anyGroup()); for(JobKey jobKey:jobKeys){ jobs.add(jobKey.getName()); } } catch (SchedulerException e) { e.printStackTrace(); } return jobs; } }首先控制台没任何打印 访问查询接口获取正在运行的定时任务,返回结果为空 http://localhost:8080/quartz/getAllJob 添加一个job http://localhost:8080/quartz/addJob?jobName=JsonTom888
再次访问查询接口获取正在运行的定时任务,返回了我们刚才添加的job名 http://localhost:8080/quartz/getAllJob 查看后台,有如下日志,说明定时任务在正常执行 我们尝试删除定时任务 http://localhost:8080/quartz/deleteJob?jobName=JsonTom888 再次访问查询接口获取正在运行的定时任务,返回结果为空 http://localhost:8080/quartz/getAllJob 查看后台日志,清空控制台日志,发现停止打印,说明我们已经成功终止定时任务 补充:实际项目中如果我们创建了大量定时任务,并希望下次重新部署服务后这些定时任务继续执行,我们可以将定时任务相关信息存入数据库,在项目启动时加载我们需要的定时任务,以达到重新部署的情况下不用重新创建定时任务。
https://github.com/JsonTom888/scheduledAndQuartz/tree/master/quartzdemo