SpringBoot配置quartz实现定时任务

JobDetail Trigger Scheduler JobDataMap 的使用

1. 基于注解实现

1.1.1 在项目启动类添加@EnableSchedulling开启定时任务管理

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
 
@SpringBootApplication
@EnableScheduling //开启定时任务
public class ScheduledDemoApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(ScheduledDemoApplication.class, args);
    }
}

1.1.2 添加定时任务类,使用@Schedule开启一个定时任务

// 也可以使用占位符
// @Schedule(cron="${startTime}")
@Schedule(cron="0 30 2 * * ?")
 public void task() {
 	// do somthing
 }

1.2 @Schedule参数详解

package org.springframework.scheduling.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
    String CRON_DISABLED = "-";
 
    String cron() default "";
 
    String zone() default "";
 
    long fixedDelay() default -1L;
 
    String fixedDelayString() default "";
 
    long fixedRate() default -1L;
 
    String fixedRateString() default "";
 
    long initialDelay() default -1L;
 
    String initialDelayString() default "";
}

1.2.1 cron

该参数接收一个cron表达式

cron 表达式语法:
格式:[秒] [分] [时] [日] [月] [周] [年]

说明是否必填允许填写的值允许的通配符
0-59, - * /
0-59, - * /
0-23, - * /
1-31, - * / ? L W
1-12 or JAN-DEC, - * /
1-7 or SUN-SAT, - * / ? L #
[1970-2099], - * /

通配符含义

***** 表示所有值,如秒设置为 ‘*****’,则表示每一秒

, 表示指定多个值,如时设置为 10,20 表示 10点,20点触发

- 表示指定区间,如时设置为 10-20,则表示10点至20点之间,每个小时都会触发

/ 表示递增触发,如分设置为 5/10,则表示从5分开始,每10分钟执行一次

? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?

L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"

W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,“W"前只能设置具体的数字,不允许区间”-")

日和周不能同时表示,需要一个用 ?

2. 手动创建定时任务

定时任务有三个重要组成部分

分别为

  • Schedule 调度器

  • Trigger 触发器

  • JobDetail 具体job

2.1 创建简单定时任务Demo

2.1.1 首先创建类实现Job 接口并重写execute() 方法,作为具体执行类
import org.quartz.Job;

public class CustomJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // do something 
    }
    
} 
2.1.2 创建触发器
Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("triggerName", "triggerGroupName") // 触发器信息
        .withSchedule(SimpleScheduleBuilder.simpleSchedule() // 指定具体的触发器类型
        .withIntervalInSeconds(1)) // 间隔1秒执行
        .startNow() // 立即生效
        .startAt(start) // 开始执行时间
        .endAt(end) // 结束执行时间
        .build();

// 需要注意的时,startNow() 和 startAt() 方法因为修改的时同一个变量
// 所以只有一个会生效,那个在后边那个就被使用
 
2.1.3 创建JobDetail
JobDetail jobDetail = JobBuilder.newJob(CustomJob.class) // job具体执行类
        .withIdentity("jobName", "jobGroupName") // job信息
        .setJobData(new JobDataMap(map)) // 任务参数
        .build(); 
2.1.4 配置调度器
Scheduler scheduler = new SchedulerFactory().getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
// or IOC 注入 
@Autowire
private Scheduler scheduler; 

// 启动调度器
scheduler.startUp(); 



经过以上步骤,一个简单的定时任务就创建完成了。

2.2 Trigger 的使用

触发类型在 withSchedule(ScheduleBuilder<SBT> schedBuilder) 方法中确定,

源码如下

public <SBT extends T> TriggerBuilder<SBT> withSchedule(ScheduleBuilder<SBT> schedBuilder) {
    this.scheduleBuilder = schedBuilder;
    return (TriggerBuilder<SBT>) this;
}

可以看到,有传递进入的参数决定了触发器的类型。

2.2.1 SimpleTrigger

简单触发器,

借助 SimpleScheduleBuilder 设定,可以设置触发器的执行间隔,以及重复次数

SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
        .withIdentity("tiggerName") // 认证信息
        .withSchedule(SimpleScheduleBuilder.simpleSchedule() 
        .withIntervalInMinutes(10) // 每10分钟执行一次
        .repeatForever()) // 无限重复
        .startNow() // 立即生效
        .build();
2.2.2 CronTrigger

常用的触发器,通过cron表达式设置触发

CronTrigger cronTrigger = TriggerBuilder.newTrigger()
        .withIdentity("cronTrigger") // 认证信息
        .withSchedule(CronScheduleBuilder.cronSchedule("0 0/20 10-12 * * ?")) //设置cron 
//        .withSchedule(CronScheduleBuilder.cronSchedule(new CronExpression("")))
        .build();
2.2.3 DailyTimeIntervalTrigger

指定每日固定时间段,固定间隔内执行,可指定星期

DailyTimeIntervalTrigger dailyTimeIntervalTrigger = TriggerBuilder.newTrigger()
        .withIdentity("dailyTimeIntervalTrigger ") // 认证信息
        .withSchedule(DailyTimeIntervalScheduleBuilder
                .dailyTimeIntervalSchedule()
                .startingDailyAt(TimeOfDay.hourAndMinuteOfDay(h, m)) // 从h点m分开始
                .endingDailyAt(TimeOfDay.hourAndMinuteOfDay(h, m)) // 到h点m分结束
                .withIntervalInSeconds(600) // 间隔10分钟执行
                .onDaysOfTheWeek(2, 3, 4)) // 每周一 二 三 执行
        .build();

// onDaysOfTheWeek() 方法接收可变数组,参数值为 1-7
// 其中1代表周日,2代表周一,以此类推 
2.2.4 CalendarIntervalTrigger

与SimpleTrigger 类似,从指定时间开始,已一定的时间间隔执行,可以支持间隔单位为 秒,分,时,天,月,周,年 适用于 每月/每年 等不是固定时间间隔的任务

 CalendarIntervalTrigger calendarIntervalTrigger = TriggerBuilder.newTrigger()
        .withIdentity("")
        .withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule()
        .withIntervalInMonths(3)) // 每三个月执行一次
        .startNow()
        .build();

2.3 带参数的任务执行

传递参数

在创建需要传递参数的任务时,可以通过Trigger 的 usingJobData() 方法传递参数

方法可通过key,value形式传递 usingJobData(key, value)

也可直接接收一个类型为JobDataMap的参数,可通过带参构造方法直接构建

JobDataMap jobDataMap = new JobDataMap(Map<k,v> map);
TriggerBuilder.newTrigger().usingJobData(jobDataMap).build(); 

或者是 JobDetail 的setJobDataMap() 和usingJobData() 方法

JobDetail jobDetail = JobBuilder.newJob(CustomJob.class)
        .setJobData(new JobDataMap(map))
        .usingJobData("key", "value")
        .withIdentity(config.getJobName(), config.getJobGroupName())
        .build();

解析参数

在任务执行过程中,通过任务上下文解析任务参数

import org.quartz.Job;

public class CustomJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        // 从jobDetail 中获取数据
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        // 从trigger中获取数据
        // JobDataMap dataMap = context.getTrigger().getJobDataMap();
        Object value = dataMap.get("key");
    }
    
}  

2.4 任务的启动,暂停,修改,移除

@Autowired
private Scheduler scheduler;

public void demo() {
  
  // 往调度器中添加一个任务
  scheduler.scheduleJob(jobDetail, trigger);
  
  // 指定触发器
  TriggerKey triggerKey = new TriggerKey("tiggerName", "triggerGroupName");
  
  // 暂停触发器
  scheduler.pauseTrigger(triggerKey);
  // 恢复触发器
  scheduler.resumeTrigger(triggerKey);
  // 移除触发器
  scheduler.unscheduleJob(triggerKey);
  // 删除任务
  scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
  
} 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值