SpringBoot整合Quartz

0.添加表

1.pom文件

        <!--SpringBoot集成QuartZ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

2.配置文件

server.port=8080

#====================数据源配置===================
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mall?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=zsq2170
# 使用druid数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#驱动com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#连接池初始化数量
spring.datasource.druid.initial-size=5
#最小空闲连接数
spring.datasource.druid.min-idle=10
#最大连接数
spring.datasource.druid.max-active=2000
#获取连接等待超时时间
spring.datasource.druid.max-wait=60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
spring.datasource.druid.time-between-eviction-runs-millis=60000

#=====================quartz任务配置=============================
# quartz任务存储类型:jdbc或memory
spring.quartz.job-store-type=jdbc
# 关闭是等待任务完成
spring.quartz.wait-for-jobs-to-complete-on-shutdown=true
# 可以覆盖已有的任务
spring.quartz.overwrite-existing-jobs=true
# 调度器实例名称
spring.quartz.properties.org.quartz.scheduler.instanceName=scheduler
# 调度器实例ID自动生成
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
# 调度信息存储处理类
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
# 使用完全兼容JDBC的驱动
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# quartz相关表前缀
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
# 是否将JobDataMap中的属性转为字符串存储
spring.quartz.properties.org.quartz.jobStore.useProperties=false
# 指定线程池实现类,对调度器提供固定大小的线程池
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 设置并发线程数量
spring.quartz.properties.org.quartz.threadPool.threadCount=10
# 指定线程优先级
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
#   配置重启任务后不执行暂停期间的任务
# 这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
spring.quartz.properties.org.quartz.jobStore.misfireThreshold = 1000



# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
spring.datasource.druid.max-evictable-idle-time-millis=900000
# 配置检测连接是否有效
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL

3.创建任务操作接口类 ScheduleService

public interface ScheduleService {
    /**
     * 通过CRON表达式调度任务
     */
    String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data);

    /**
     * 通过CRON表达式调度任务 ,设置结束时间
     */
    String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data,Date endDate);

    /**
     * 通过CRON表达式调度任务,设置开始和结束时间
     */
    String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data,Date startDate,Date endDate);

    /**
     * 调度指定时间的任务
     */
    String scheduleFixTimeJob(Class<? extends Job> jobBeanClass, Date startTime, String data);

    /**
     * 取消定时任务
     */
    Boolean cancelScheduleJob(String jobName);

    /**
     * 暂停定时任务
     */
    Boolean pauseJob(String jobName);

    /**
     * 重启定时任务
     */
    Boolean resumeJob(String jobName);

}

4.任务操作实现类 ScheduleServiceImpl

@Slf4j
@Service
public class ScheduleServiceImpl implements ScheduleService {
    @Autowired
    private Scheduler scheduler;
    private String defaultGroup = "default_group"; //任务组

    @Override
    public String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data) {
        return scheduleJob(jobBeanClass,cron,data,new Date(),null);
    }

    /**
     * 通过CRON表达式调度任务 ,设置结束时间
     */
    @Override
    public String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data, Date endDate) {
        return scheduleJob(jobBeanClass,cron,data,new Date(),endDate);
    }

    /**
     * 通过CRON表达式调度任务,设置开始和结束时间
     */
    @Override
    public String scheduleJob(Class<? extends Job> jobBeanClass, String cron, String data, Date startDate, Date endDate) {
        // 创建需要执行的任务
        String jobName = UUID.fastUUID().toString().replaceAll("-","");
        JobDetail jobDetail = JobBuilder.newJob(jobBeanClass)
                .withIdentity(jobName, defaultGroup)
                .usingJobData("data", data)
                .build();
        //创建触发器,指定任务执行时间
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(jobName, defaultGroup)
                .startAt(startDate)
                .endAt(endDate)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron)
                        .withMisfireHandlingInstructionDoNothing()) //添加此配置 ,重启不执行之前暂停期间该 执行的任务
                .build();
        //使用调度器进行任务调度
        try {
            scheduler.scheduleJob(jobDetail, cronTrigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.info("创建定时任务失败!");
        }
        return jobName;
    }

    @Override
    public String scheduleFixTimeJob(Class<? extends Job> jobBeanClass, Date startTime, String data) {
        //日期转CRON表达式
        String startCron = String.format("%d %d %d %d %d ? %d",
                DateUtil.second(startTime),
                DateUtil.minute(startTime),
                DateUtil.hour(startTime, true),
                DateUtil.dayOfMonth(startTime),
                DateUtil.month(startTime) + 1,
                DateUtil.year(startTime));
        return scheduleJob(jobBeanClass, startCron, data);
    }

    @Override
    public Boolean cancelScheduleJob(String jobName) {
        boolean success = false;
        try {
            // 暂停触发器
            scheduler.pauseTrigger(new TriggerKey(jobName, defaultGroup));
            // 移除触发器中的任务
            scheduler.unscheduleJob(new TriggerKey(jobName, defaultGroup));
            // 删除任务
            scheduler.deleteJob(new JobKey(jobName, defaultGroup));
            success = true;
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return success;
    }

    /**
     * 暂停定时任务
     */
    @Override
    public Boolean pauseJob(String jobName) {
        boolean success = false;
        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobName,defaultGroup));
            success = true;
        }catch (SchedulerException e){
            e.printStackTrace();
        }
        return success;
    }

    /**
     * 重启定时任务
     */
    @Override
    public Boolean resumeJob(String jobName) {
        boolean success = false;
        try {
            scheduler.resumeTrigger(TriggerKey.triggerKey(jobName,defaultGroup));
            success = true;
        }catch (SchedulerException e){
            e.printStackTrace();
        }
        return success;
    }
}

5.添加发送邮件和发送短信和CRON表达式任务类继承  QuartzJobBean  或者实现Job接口都行

/**
 * 发送邮件定时任务执行器
 * Created by macro on 2020/9/27.
 */
@Slf4j
@Component
public class SendEmailJob extends QuartzJobBean {
    @Autowired
    private ScheduleService scheduleService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Trigger trigger = jobExecutionContext.getTrigger();
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        String data = jobDataMap.getString("data");
        log.info("定时发送邮件操作:{}",data);
        //完成后删除触发器和任务
        scheduleService.cancelScheduleJob(trigger.getKey().getName());
    }
}
@Slf4j
@Component
public class SendEmailJob extends QuartzJobBean {
    @Autowired
    private ScheduleService scheduleService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        Trigger trigger = jobExecutionContext.getTrigger();
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        String data = jobDataMap.getString("data");
        log.info("定时发送邮件操作:{}",data);
        //完成后删除触发器和任务
        scheduleService.cancelScheduleJob(trigger.getKey().getName());
    }
}
/**
 * 使用CRON表达式的任务执行器
 * Created by macro on 2020/9/29.
 */
@Slf4j
@Component
public class CronProcessJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDetail jobDetail = jobExecutionContext.getJobDetail();
        JobDataMap jobDataMap = jobDetail.getJobDataMap();
        String data = jobDataMap.getString("data");
        log.info("CRON表达式任务执行:{}",data);
    }
}

6.添加Controller,测试任务 

/**
 * 定时任务调度相关接口
 * Created by macro on 2020/9/29.
 */
@Api(tags = "ScheduleController", description = "定时任务调度相关接口")
@RestController
@RequestMapping("/schedule")
public class ScheduleController {
    @Autowired
    private ScheduleService scheduleService;

    @ApiOperation("定时发送邮件")
    @PostMapping("/sendEmail")
    public CommonResult sendEmail(@RequestParam String startTime, @RequestParam String data) {
        Date date = DateUtil.parse(startTime, DatePattern.NORM_DATETIME_FORMAT);
        String jobName = scheduleService.scheduleFixTimeJob(SendEmailJob.class, date, data);
        return CommonResult.success(jobName);
    }

    @ApiOperation("定时发送站内信")
    @PostMapping("/sendMessage")
    public CommonResult sendMessage(@RequestParam String startTime, @RequestParam String data) {
        Date date = DateUtil.parse(startTime, DatePattern.NORM_DATETIME_FORMAT);
        String jobName = scheduleService.scheduleFixTimeJob(SendMessageJob.class, date, data);
        return CommonResult.success(jobName);
    }

    @ApiOperation("通过CRON表达式调度任务")
    @PostMapping("/scheduleJob")
    public CommonResult scheduleJob(@RequestParam String cron, @RequestParam String data) {
        String jobName = scheduleService.scheduleJob(CronProcessJob.class, cron, data);
        return CommonResult.success(jobName);
    }

    @ApiOperation("取消定时任务")
    @PostMapping("/cancelScheduleJob")
    public CommonResult cancelScheduleJob(@RequestParam String jobName) {
        Boolean success = scheduleService.cancelScheduleJob(jobName);
        return CommonResult.success(success);
    }

    @ApiOperation("暂停定时任务")
    @PostMapping("/pauseJob")
    public CommonResult pauseJob(@RequestParam String jobName) {
        Boolean success = scheduleService.pauseJob(jobName);
        return CommonResult.success(success);
    }

    @ApiOperation("重启定时任务")
    @PostMapping("/resumeJob")
    public CommonResult resumeJob(@RequestParam String jobName) {
        Boolean success = scheduleService.resumeJob(jobName);
        return CommonResult.success(success);
    }
}

7.测试效果

8.配置暂停重启,  暂停之后重启,会默认执行暂停期间该执行但丢失的任务,如下图

需要配置不执行暂停期间的任务,需要加配置如下

1.配置文件添加配置

#   配置重启任务后不执行暂停期间的任务
# 这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
spring.quartz.properties.org.quartz.jobStore.misfireThreshold = 1000

2.创建任务时,设置类型

 

源码地址 : 链接:https://pan.baidu.com/s/1Bbr9AuQhOGX7XIhghPA2KA    提取码:zsq6 

本文参考Git上mall商城项目大佬的公众号文档 ,在他原代码上查资料并修改,比原文更加丰富

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值