Springboot实现quartz定时

来源:互联网 发布:java预约系统源代码 编辑:程序博客网 时间:2024/05/19 23:01

需要声明的是,本篇博客参考了springboot整合Quartz实现动态配置定时任务和 spring boot整合quartz实现多个定时任务。其中的大部分代码都是参考这两篇博客中的代码。在此感谢博主!
因为项目中需要用到比较复杂的定时,就看了下quartz。参考了上面的两篇博客,算是个demo吧。
简单理解,quartz的定时可以大致分为两部分,一种时单任务,一种是多任务。
需要引入的依赖:

<dependency>     <groupId>org.quartz-scheduler</groupId>    <artifactId>quartz</artifactId>    <version>2.2.1</version></dependency>

1,quartz单任务

添加一个任务

@Configuration@Component@EnableScheduling // 该注解必须要加public class ScheduleTask {      public void scheduleTest() {         System.err.println("scheduleTest开始定时执行");    }}

配置:

@Configurationpublic class QuartzConfigration {    @Bean(name = "jobDetail")      public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {        // ScheduleTask为需要执行的任务          MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();          /*          *  是否并发执行          *  例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,          *  如果此处为true,则下一个任务会bing执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行          */          jobDetail.setConcurrent(true);          jobDetail.setName("scheduler");// 设置任务的名字          jobDetail.setGroup("scheduler_group");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用          /*          * 这两行代码表示执行task对象中的scheduleTest方法。定时执行的逻辑都在scheduleTest。         */          jobDetail.setTargetObject(task);          jobDetail.setTargetMethod("scheduleTest");          return jobDetail;      }     @Bean(name = "jobTrigger")      public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {          CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();          tigger.setJobDetail(jobDetail.getObject());          tigger.setCronExpression("0/6 * * * * ?");// 表示每隔6秒钟执行一次        //tigger.set        tigger.setName("myTigger");// trigger的name          return tigger;      }    @Bean(name = "scheduler")      public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {          SchedulerFactoryBean bean = new SchedulerFactoryBean();        //设置是否任意一个已定义的Job会覆盖现在的Job。默认为false,即已定义的Job不会覆盖现有的Job。        bean.setOverwriteExistingJobs(true);          // 延时启动,应用启动5秒后  ,定时器才开始启动        bean.setStartupDelay(5);          // 注册定时触发器          bean.setTriggers(cronJobTrigger);          return bean;      }    //多任务时的Scheduler,动态设置Trigger。一个SchedulerFactoryBean可能会有多个Trigger    @Bean(name = "multitaskScheduler")     public SchedulerFactoryBean schedulerFactoryBean(){          SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();           return schedulerFactoryBean;       }}

项目启动5秒后,定时器开始启动。
截图如下:
这里写图片描述

在Controller中动态改变tigger表达式

@Controllerpublic class QuartzController {    @Resource(name = "jobDetail")      private JobDetail jobDetail;      @Resource(name = "jobTrigger")      private CronTrigger cronTrigger;      @Resource(name = "scheduler")      private Scheduler scheduler;/*  @Resource(name="haha")    private UseFunctionService useFunctionService;    @Resource    private FunctionDao functionDao;*/    @ResponseBody    @RequestMapping("/{prod}/quart")    public String quartzTest(@PathVariable Integer prod) throws SchedulerException{         CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());           String currentCron = trigger.getCronExpression();// 当前Trigger使用的           System.err.println("当前trigger使用的-"+currentCron);         //1秒钟执行一次         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");           // 按新的cronExpression表达式重新构建trigger           trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());           trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey())                   .withSchedule(scheduleBuilder).build();           // 按新的trigger重新设置job执行           scheduler.rescheduleJob(cronTrigger.getKey(), trigger);          return prod+"-这是quartz测试";    }}

在浏览器中访问该controller后,scheduleTest方法1秒钟执行一次。

总结:quartz执行单任务,需要自定义一个Task类并将定时执行的逻辑写在方法里面。MethodInvokingJobDetailFactoryBean中配置任务的名字和分组,设置定时执行逻辑的对象和方法。CronTriggerFactoryBean中配置MethodInvokingJobDetailFactoryBean的实例以及定时表达式。SchedulerFactoryBean设置启动时机,注册触发器(即为Trigger对象)。

2,quartz多任务

quartz多任务需要用到Job类,将定时的逻辑写在Job类中。
定义两个Job表示两个任务:

public class ScheduledJob implements Job {    @Override    public void execute(JobExecutionContext context)            throws JobExecutionException {         System.err.println("这是第一个任务 is running…………………………………… ");      }}
public class ScheduledJob2 implements Job {    @Override    public void execute(JobExecutionContext context)            throws JobExecutionException {         System.err.println("第二个任务正在运行 is running…………………………………… ");      }}

在Controller中启动定时任务:

@Controllerpublic class QuartzController {    @Resource(name="multitaskScheduler")    private Scheduler scheduler2;    @ResponseBody    @RequestMapping("/multitask")    public String multitask() throws SchedulerException {        scheduleJob2(scheduler2);        return "多任务";    }    @ResponseBody    @RequestMapping("/multitask2")    public String multitask2() throws SchedulerException {        scheduleJob(scheduler2);        return "这个也是多任务";    }    //具体的定时任务    private void scheduleJob2(Scheduler scheduler) throws SchedulerException{       //配置定时任务对应的Job,这里执行的是ScheduledJob类中定时的方法        JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class) .withIdentity("job2", "group1").build();          CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");           // 每3s执行一次          CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1") .withSchedule(scheduleBuilder).build();           scheduler.scheduleJob(jobDetail,cronTrigger);      }    private void scheduleJob(Scheduler scheduler) throws SchedulerException{       //配置定时任务对应的Job,这里执行的是ScheduledJob2类中定时的方法           JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class) .withIdentity("job1", "group1").build();          CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?");           // 每6s执行一次          CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1") .withSchedule(scheduleBuilder).build();           scheduler.scheduleJob(jobDetail,cronTrigger);      }}

执行效果如下图:
这里写图片描述
总结:quartz多任务,有多少任务就有多少个Job。
关于cronExpression表达式,可以参考这篇文章,说得很清楚,感谢博主。cronExpression参考文章