SpringBoot整合Quertz定时器

Maven依赖:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
</dependency>

Quertz数据表(MySQL):

CREATE TABLE `sys_task` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `job_name` varchar(255) DEFAULT NULL COMMENT '任务名',
  `description` varchar(255) DEFAULT NULL COMMENT '任务描述',
  `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式',
  `bean_class` varchar(255) DEFAULT NULL COMMENT '任务执行时调用哪个类的方法 包名+类名',
  `job_status` varchar(255) DEFAULT NULL COMMENT '任务状态',0:停止1:运行,
  `job_group` varchar(255) DEFAULT NULL COMMENT '任务分组',
  `create_user` varchar(64) DEFAULT NULL COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_user` varchar(64) DEFAULT NULL COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;

INSERT INTO `sys_task` VALUES ('1', 'QuertzTask1', 'Quertz定时器测试一', '0/10 * * * * ?', 'com.example.demo.Quertz.TestQuertzTask', '1', 'group', null, null, null, null);

Quertz配置:

package com.example.demo.Quertz;

import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.io.IOException;
import java.util.Properties;

@Configuration
public class QuartzConfigration {
    @Autowired
    private JobFactory jobFactory;

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        try {
            schedulerFactoryBean.setOverwriteExistingJobs(true);
            schedulerFactoryBean.setQuartzProperties(quartzProperties());
            schedulerFactoryBean.setJobFactory(jobFactory);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return schedulerFactoryBean;
    }

    // 指定quartz.properties,可在配置文件中配置相关属性
    @Bean
    public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("/config/quartz.properties"));
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }

    // 创建schedule
    @Bean(name = "scheduler")
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }
}
package com.example.demo.Quertz;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

@Component
public class JobFactory extends AdaptableJobFactory {
    //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
    //为什么需要这个类呢,在我写的这个demo中,大家可以将此类删掉,发现程序也可以政策运营,可是我为什么还是加上呢。
    //大家可以看下我们的任务类,大家可以看到Job对象的实例化过程是在Quartz中进行的,这时候我们将spring的东西注入进来,肯定是行不通的,所以需要这个类
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

SpringBoot启动加载定时器任务(实现接口 CommandLineRunner 来实现):

package com.example.demo.Quertz;

import com.example.demo.Entity.Task;
import com.example.demo.Service.QuertzTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Order(value = 1)
public class QuartzTask implements CommandLineRunner {
    @Autowired
    private QuertzTaskService quertzTaskService;
    @Autowired
    private QuertzManage quertzManage;
    @Override
    public void run(String... arg0) throws Exception {
        List<Task> taskList = quertzTaskService.queryQuertzTask();
        for (Task task : taskList) {
            quertzManage.addJob(task);
        }

    }
}

Quertz定时器启动,暂停,运行等封装:

package com.example.demo.Quertz;

import com.example.demo.Entity.Task;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class QuertzManage {

    @Autowired
    private Scheduler scheduler;

    /**
     * 添加一个job
     * @param task
     */
    public void addJob(Task task) {
        try {
            // 创建jobDetail实例,绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定job类

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

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

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

    /**
     * 立即执行一个job
     * @param jobName
     * @param jobGroup
     * @throws SchedulerException
     */
    public void runJobNow(String jobName,String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        scheduler.triggerJob(jobKey);
    }
}

SpringDataJPA查询接口:

package com.example.demo.Service;

import com.example.demo.Entity.Task;
import org.quartz.SchedulerException;

import java.util.List;

public interface QuertzTaskService {

    List<Task> queryQuertzTask();

    void pauseTaskById(String id) throws SchedulerException;

    void resumeTaskById(String id) throws SchedulerException;

}

接口实现方法:

package com.example.demo.Service.Impl;

import com.example.demo.Entity.Task;
import com.example.demo.Quertz.QuertzManage;
import com.example.demo.Repository.TaskRepository;
import com.example.demo.Service.QuertzTaskService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class QuertzTaskServiceImpl implements QuertzTaskService {
    @Autowired
    private TaskRepository  taskRepository;
    @Autowired
    private QuertzManage quertzManage;
    @Override
    public List<Task> queryQuertzTask() {
        return taskRepository.findByJobStatus();
    }

    @Override
    public void pauseTaskById(String id) throws SchedulerException {
        Optional<Task> task = taskRepository.findById(id);
        quertzManage.pauseJob(task.get().getJobName(),task.get().getJobGroup());
    }

    @Override
    public void resumeTaskById(String id) throws SchedulerException {
        Optional<Task> task = taskRepository.findById(id);
        quertzManage.resumeJob(task.get().getJobName(),task.get().getJobGroup());
    }
}

定时任务:

package com.example.demo.Quertz;


import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

@DisallowConcurrentExecution //作业不并发
@Component
public class TestQuertzTask implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Quertz定时器: "+dateFormat.format(new Date()));
    }
}

源码:https://github.com/zeng-xian-guo/springboot_jwt_token.git

参考:https://blog.csdn.net/qq_40065776/article/details/107489728

          小卖铺的老爷爷:https://github.com/allanzhuo/yyblog

原文地址:https://www.cnblogs.com/zxg-6/p/13783228.html