spring booth整合quartz框架

引入quartz# 系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、提前准备工作

1.到quartz官网下载自己需要的版本
http://www.quartz-scheduler.org/downloads/
2.我下载的是2.3.0版本,解压之后如下
quarz官网解压

3.在解压之后的如下文件夹下,有quartz所需要的建表语句,选择跟你的数据库相一致的sql执行
quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore。我选择的是tables_mysql_innodb.sql

执行自己需要的数据库类型建表语句
4.执行之后再自己的数据库中即得到如下这些表格
quartz表格

5.quartz表格的作用,如下:
QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信息
QRTZ_CRON_TRIGGERS 存储 Cron Trigger,包括 Cron表达式和时区信息
QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息 QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger 组的信息
QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler 的状态信息,和别的 Scheduler实例(假如是用于一个集群中)
QRTZ_LOCKS 存储程序的悲观锁的信息(假如使用了悲观锁)
QRTZ_JOB_DETAILS 存储每一个已配置的 Job 的详细信息
QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener 的信息
QRTZ_SIMPLE_TRIGGERS 存储简单的Trigger,包括重复次数,间隔,以及已触的次数
QRTZ_BLOG_TRIGGERS Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC创建他们自己定制的 Trigger 类型,JobStore 并不知道如何存储实例的时候)
QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener 的信息
QRTZ_TRIGGERS 存储已配置的 Trigger 的信息

二、使用步骤

1.引入库

这里是引用

pom文件中添加如下依赖:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <!--quartz的启动数据源依赖c3p0,所以还需要引入该依赖,否则启动时有问题,可自己验证一下-->
         <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.5</version>
        </dependency>

2.读入数据

定时处理器基本的增删改查,如下只做参考:

@Slf4j
@RestController
@RequestMapping("/quartz")
public class QuartzJobController {
    @Autowired
    private JobExecuteDetailsService jobExecuteDetailsService ;
    @Autowired
    @Qualifier("CronScheduler")
    private Scheduler cronScheduler;
    @Autowired
    private JobExecuteDetailsMapper jobExecuteDetailsMapper;

    /**
     * 添加定时任务
     *
     * @param vo
     * @return
     */
    @PostMapping("/addQuartz")
    @ResponseBody
    public String addQuartz(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("新增任务:"+vo.getJobName());
        JobKey jobKey = new JobKey(vo.getJobName(), vo.getJobGroupName());
        vo.setJobCreated(new Date());
        try {
            if (null == cronScheduler.getJobDetail(jobKey)) {
                cronScheduler.deleteJob(jobKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        try {
            Class clz = Class.forName(vo.getJobClassName());
            clz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        int tableId = jobExecuteDetailsMapper.insert(JobExecuteDetailsMapstruct.INSTANCE.voToDo(vo));
        JobDetail jobDetail = JobBuilder.newJob(QquartzJob.class)
                .usingJobData("command", vo.getCommand())
                .usingJobData("tableId", tableId)
                .withIdentity(vo.getJobName(), vo.getJobGroupName())
                .build();
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger" + vo.getJobName(), "triggetGroup")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(vo.getCron()))
                .build();
        try {
            cronScheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return "新增定时任务"+vo.getJobName()+"成功";
    }
    /**
     * 立即执行一次定时任务
     */
    @PostMapping("/trigger")
    public  String trigger(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("单次触发定时任务:"+vo.getJobName());
        try {
            JobKey key = new JobKey(vo.getJobName(),vo.getJobGroupName());
            cronScheduler.triggerJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
             log.error("单次触发定时任务:"+vo.getJobName()+"失败");
        }
        return "ok";
    }

    /**
     * 查看所有定时任务
     *
     * @param param
     * @return
     */
    @PostMapping(value = "/batchPageJobList")
    public AppResult<Page<JobExecuteDetailsVO>> batchPageJobList(@RequestBody JobExecuteDetailParam param) {
        try {
            return AppResultBuilder.success(jobExecuteDetailsService.batchPageJobList(param));
        } catch (Exception e) {
            log.error("分页查询任务列表,异常", e);
            return AppResultBuilder.fail("查询失败,系统异常");
        }
    }

    /**
     * 根据id删除定时任务  同时需要删除对应的触发器
     *
     * @param vo
     */
    @PostMapping("/deleteJob")
    public void deleteJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("删除定时任务"+vo.getJobName());
        String jobName=vo.getJobName();
        String jobGroupGroupName=vo.getJobGroupName();
        TriggerKey triggerKey= TriggerKey.triggerKey(jobName,jobGroupGroupName);
        JobKey jobKey=new JobKey(jobName,jobGroupGroupName);
        try {
            cronScheduler.pauseTrigger(triggerKey);
            cronScheduler.unscheduleJob(triggerKey);
            cronScheduler.deleteJob(jobKey);
            jobExecuteDetailsMapper.deleteById(vo.getId());
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("删除定时任务"+vo.getJobName()+"失败");
        }
    }


    /**
     * 暂停/终止定时任务
     *
     * @param vo
     */
    @PostMapping("/pauseJob")
    public void pauseJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("停止任务"+vo.getJobName());
        JobKey jobKey=new JobKey(vo.getJobName(),vo.getJobGroupName());
        try {
            cronScheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("停止任务"+vo.getJobName()+"失败");
        }
    }

    /**
     * 继续执行定时任务
     *
     * @param vo
     */
    @PostMapping("/resumeJob")
    public void resumeJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("恢复任务");
        JobKey jobKey=new JobKey(vo.getJobName(),vo.getJobGroupName());
        try {
            cronScheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("恢复任务"+vo.getJobName()+"失败");
        }
    }

}

3.踩过的坑

1.quartz的Job类不受spring管理,因此Job中如果想要注入对象,是需要单独创建一个管理类进行引入。管理类如下

@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;

public static ApplicationContext getApplicationContext() {
    return applicationContext;
}


@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    ApplicationContextUtil.applicationContext = applicationContext;

}


public static Object getBean(String beanName) {
    return applicationContext.getBean(beanName);
}
}

2.在Job中引用的时候可以参考如下代码

private JobExecuteDetailsService jobExecuteDetailsService = (JobExecuteDetailsService) ApplicationContextUtil.getBean("jobExecuteDetailsServiceImpl");

3.因为quartz是不受spring管理的,因此quartz的配置文件quartz.properties 中需要添加单独数据源配置
参考如下:

org.quartz.threadPool.threadCount = 5
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS

org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL =
org.quartz.dataSource.myDS.user =
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections =5

总结

到此为止就是我在spring boot整合quartz额过程,以及这个过程中踩过的一些坑,大家可以参考一下,完整的工程代码稍后会更新到github上。可能版本不一致,遇到的问题也不一样,祝你们成功~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值