springboot2.x整合quartz2.x.md

Posted 音译昌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot2.x整合quartz2.x.md相关的知识,希望对你有一定的参考价值。

简介

What is the Quartz Job Scheduling Library?
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.(Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中——从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的调度,以执行数万、数百甚至数万个作业;任务被定义为标准Java组件的作业,这些组件可以执行几乎任何您可以编程让它们执行的任务。Quartz调度器包含许多企业级特性,比如对JTA事务和集群的支持。)
来之官网介绍

实例实践

1. 加入依赖

    <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

2. 代码

  • 任务实例类
    @Data
    @Table(name = "sys_task")
    public class Task extends BaseEntity implements Serializable {
        private static final long serialVersionUID = 1L;

        //cron表达式
        private String cronExpression;
        //任务调用的方法名
        private String methodName;
        //任务是否有状态
        private String isConcurrent;
        //任务描述
        private String description;
        //任务状态
        private Integer jobStatus;
        //任务分组
        private String jobGroup;
        //Spring bean
        private String springBean;
        //任务名
        private String jobName;
        //任务类
        private String beanClass;

    }
  • service层接口
    @Service
    public class TaskServiceImpl extends BaseServiceImpl<TaskWriteMapper, TaskReadMapper, Task> implements TaskService {

        @Autowired
        private TaskWriteMapper taskWriteMapper;




         /**
         * 保存数据
         * @param task
         * @return
         */
        @Override
        @Transactional(rollbackFor = RuntimeException.class)
        public int saveData(Task task){
            int result=task.getId()==null?taskWriteMapper.insert(task):taskWriteMapper.updateByPrimaryKey(task);
            return result;
        }

        /**
         * 列表数据
         * @param keyword
         * @param index
         * @param size
         * @return
         */
        @Override
        public PageData<Task> selectTaskList(String keyword, int index, int size){
            Example example=new Example(Task.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andLike("jobName", "%"+ keyword +"%");
            PageData<Task> list = selectPage(example, index, size);
            return list;
        }
    }
    
    @Service
public class QuartzTaskServiceImpl extends TaskServiceImpl implements QuartzTaskService {



    @Autowired
    QuartzManager quartzManager;


    /**
     * 初始化定时任务
     */
    @Override
    public void initSchedule() {
        Example e=new Example(Task.class);
        List<Task> list=selectByExample(e);
        //lambda表达式
        list.forEach((t)->{
            if(t.getJobStatus()==1){
                quartzManager.addJob(t);
            }
        });
    }

    /**
      * @Description 添加任务
      * @param task
      * @Return int
      * @Author Mr.Walloce
      * @Date 2019/11/14 16:53
      */
    @Override
    public int saveTask(Task task) throws SchedulerException {
        int result = super.saveData(task);
        if (result == 0) {
            return result;
        }

        // 有修改则更新调度器信息
        if (task.getJobStatus() == 1 && quartzManager.isExsitsTask(task)) {
            quartzManager.updateJobCron(task);
        } else if (task.getJobStatus() == 1) {
            quartzManager.addJob(task);
        } else {
            quartzManager.deleteJob(task);
        }
        return result;
    }

        /**
          * @Description TODO
          * @param ids 删除任务
          * @Return int
          * @Author Mr.Walloce
          * @Date 2019/11/15 16:00
          */
        @Override
        public int deleteTask(String ids) throws SchedulerException {
            String[] idLst = ids.split(",");
            Task task = null;
            int result = 0;
            for (String id : idLst) {
                task = super.selectOne(Integer.valueOf(id));
                if (task == null) {
                    continue;
                }
                result += super.delete(task);
                quartzManager.deleteJob(task);
            }
            return result;
        }
    }
  • 计划任务管理类
    import com.vane.syscore.sys.entity.Task;
    import lombok.extern.slf4j.Slf4j;
    import org.quartz.*;
    import org.quartz.DateBuilder.IntervalUnit;
    import org.quartz.impl.matchers.GroupMatcher;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;

    /**
     * @title: QuartzManager.java
     * @description: 计划任务管理
     *
     */
    @Slf4j
    @Service
    public class QuartzManager {

        @Autowired
        private Scheduler scheduler;

        /**
         * 添加任务
         *
         * @param job
         * @throws SchedulerException
         */

        public void addJob(Task job) {
            try {
                // 创建jobDetail实例,绑定Job实现类
                // 指明job的名称,所在组的名称,以及绑定job类

                Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(job.getBeanClass()).newInstance()
                        .getClass());
                JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(job.getJobName(), job.getJobGroup())// 任务名称和组构成任务key
                        .build();
                // 定义调度触发规则
                // 使用cornTrigger规则
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())// 触发器key
                        .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
                        .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())).startNow().build();
                // 把作业和触发器注册到任务调度中
                scheduler.scheduleJob(jobDetail, trigger);
                // 启动
                if (!scheduler.isShutdown()) {
                    scheduler.start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 获取所有计划中的任务列表
         *
         * @return
         * @throws SchedulerException
         */
        public List<Task> getAllJob() throws SchedulerException {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            List<Task> jobList = new ArrayList<Task>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Task job = new Task();
                    job.setJobName(jobKey.getName());
                    job.setJobGroup(jobKey.getGroup());
                    job.setDescription("触发器:" + trigger.getKey());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    job.setJobStatus(triggerState.ordinal());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        job.setCronExpression(cronExpression);
                    }
                    jobList.add(job);
                }
            }
            return jobList;
        }

        /**
         * 所有正在运行的job
         *
         * @return
         * @throws SchedulerException
         */
        public List<Task> getRunningJob() throws SchedulerException {
            List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
            List<Task> jobList = new ArrayList<Task>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                Task job = new Task();
                JobDetail jobDetail = executingJob.getJobDetail();
                JobKey jobKey = jobDetail.getKey();
                Trigger trigger = executingJob.getTrigger();
                job.setJobName(jobKey.getName());
                job.setJobGroup(jobKey.getGroup());
                job.setDescription("触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                job.setJobStatus(Integer.valueOf(triggerState.name()));
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    job.setCronExpression(cronExpression);
                }
                jobList.add(job);
            }
            return jobList;
        }

        /**
         * 暂停一个job
         *
         * @param Task
         * @throws SchedulerException
         */
        public void pauseJob(Task Task) throws SchedulerException {
            JobKey jobKey = JobKey.jobKey(Task.getJobName(), Task.getJobGroup());
            scheduler.pauseJob(jobKey);
        }

        /**
         * 恢复一个job
         *
         * @param Task
         * @throws SchedulerException
         */
        public void resumeJob(Task Task) throws SchedulerException {
            JobKey jobKey = JobKey.jobKey(Task.getJobName(), Task.getJobGroup());
            scheduler.resumeJob(jobKey);
        }

        /**
         * 删除一个job
         *
         * @param Task
         * @throws SchedulerException
         */
        public void deleteJob(Task Task) throws SchedulerException {
            JobKey jobKey = JobKey.jobKey(Task.getJobName(), Task.getJobGroup());
            scheduler.deleteJob(jobKey);

        }

        /**
         * 立即执行job
         *
         * @param Task
         * @throws SchedulerException
         */
        public void runAJobNow(Task Task) throws SchedulerException {
            JobKey jobKey = JobKey.jobKey(Task.getJobName(), Task.getJobGroup());
            scheduler.triggerJob(jobKey);
        }

        /**
         * 更新job时间表达式
         *
         * @param Task
         * @throws SchedulerException
         */
        public void updateJobCron(Task Task) throws SchedulerException {

            TriggerKey triggerKey = TriggerKey.triggerKey(Task.getJobName(), Task.getJobGroup());

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(Task.getCronExpression());

            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            scheduler.rescheduleJob(triggerKey, trigger);
        }

        public boolean isExsitsTask(Task task) throws SchedulerException {
            boolean result = false;
            List<Task> runningJobs = this.getAllJob();
            for (Task runningJob : runningJobs) {
                if ((task.getJobGroup() + task.getJobName()).equals(runningJob.getJobGroup() + runningJob.getJobName())) {
                    result = true;
                    break;
                }
            }
            return result;
        }
    }
  • 项目启动时加载任务
    @Component
    @Order(value = 1)
    public class TaskListener implements CommandLineRunner {

        @Autowired
        QuartzTaskService taskService;

        @Autowired
        QuartzManager quartzManager;

        @Override
        public void run(String... arg0) throws Exception {
            try {
                taskService.initSchedule();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

CommandLineRunner是SpringBoot构建项目时,预先加载一些数据。如果有多个数据要加载,则添加@Order(value=1)来指定加载顺序

  • 测试任务
    @Component
    public class MyJob implements Job {
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            System.out.println("我的测试任务,2s执行一侧");
        }
    }
  • 测试数据
    INSERT INTO `vane-cloud`.`sys_task` (`id`, `cron_expression`, `method_name`, `is_concurrent`, `description`, `update_by`, `bean_class`, `create_time`, `job_status`, `job_group`, `update_time`, `create_by`, `spring_bean`, `job_name`, `delete_flag`, `order_num`) 以上是关于springboot2.x整合quartz2.x.md的主要内容,如果未能解决你的问题,请参考以下文章

springboot2.x整合kafka

SpringBoot2.x整合WebSoket

SpringBoot2.x 整合Redis和使用Redis缓存

SpringBoot2.X整合Redis

springboot2.x版本整合redis(单机/集群)(使用lettuce)

SpringBoot2.x整合Prometheus+Grafana附源码