springboot动态配置quartz+线程池

本文介绍了如何在SpringBoot应用中配置Quartz,包括quartz.properties的设置,自定义QuartzConfig配置类,创建QuartzManage工具类以管理和启动定时任务,定义Job类来执行具体任务,以及设计QuartzJob实体类和对应的控制器JobJobWController。通过这些步骤,实现了对定时任务的动态配置和管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、quartz.properties配置

org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 20
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

2、创建一个配置类,用于QuartZ的启动配置-QuartZConfig:

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName: QuartZConfig
 * @Description:
 * @Author jm
 * @Date 2022/6/11
 * @Version 1.0
 */
@Configuration
public class QuartZConfig {

    /**
     * quartz 启动配置
     */
    @Bean
    public SchedulerFactory quartz() throws SchedulerException {
        // Creating scheduler factory and scheduler
        SchedulerFactory factory = new StdSchedulerFactory("quartz.properties");
        Scheduler scheduler = factory.getScheduler();
        scheduler.start();
        return factory;
    }

}

3、QuartzManage 定时任务工具类

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

/**
 * quartz定时任务工具类,对任务进行管理(创建、修改、删除、暂停)
 *
 * @author lyf
 */
@Slf4j
public class QuartzManage {

    private static final SchedulerFactory SCHEDULER_FACTORY = new StdSchedulerFactory();
    /**
     * 启动调度任务
     *
     * @param jobDetail 执行任务
     * @param trigger   触发器
     */
    private static void startScheduler(JobDetail jobDetail, Trigger trigger) {
        try {
            // 获取调度任务实例
            Scheduler scheduler = SCHEDULER_FACTORY.getScheduler();
            // 绑定触发器和调度任务
            scheduler.scheduleJob(jobDetail, trigger);
            // 启动
            scheduler.start();
        } catch (SchedulerException e) {
            String msg = "启动调度任务失败";
            log.error(msg, e);
            //throw new Exception(msg);
        }
    }

    /**
     * 任务执行实例
     *
     * @param jobName      任务名称
     * @param jobGroupName 任务分组名
     * @param jobDataMap   执行参数
     * @param jobClass     执行类-实现了{@code org.quartz.Job}接口的类
     * @return {@link JobDetail}
     */
    private static JobDetail getJobDetail(String jobName, String jobGroupName, JobDataMap jobDataMap, Class<? extends Job> jobClass) {
        // 获取任务执行类的实例
        JobBuilder jobBuilder = JobBuilder.newJob(jobClass);
        // 添加任务名,任务组
        jobBuilder.withIdentity(jobName, jobGroupName);
        // 添加任务执行的参数
        if (jobDataMap != null && jobDataMap.size() > 0) {
            jobBuilder.setJobData(jobDataMap);
        }
        // 获取job执行实例
        return jobBuilder.build();
    }

    /**
     * cron触发器
     *
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器分组名
     * @param cron             定时策略
     * @return {@link CronTrigger}
     */
    private static CronTrigger getCronTrigger(String triggerName, String triggerGroupName, String cron) {
        // 触发器
        TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
        // 触发器名,触发器组
        triggerBuilder.withIdentity(triggerName, triggerGroupName);
        // 触发器时间设定
        triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
        // 从当前时间判断触发
        triggerBuilder.startNow();
        // 创建Trigger对象
        return (CronTrigger) triggerBuilder.build();
    }

    /**
     * 一次任务触发器
     *
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器分组名
     * @return {@link SimpleTrigger}
     */
    private static SimpleTrigger getOnceTrigger(String triggerName, String triggerGroupName) {
        // 触发器
        TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
        // 触发器名,触发器组
        triggerBuilder.withIdentity(triggerName, triggerGroupName);
        // 5秒后立即执行,重复次数设为0,表示只执行一次
        triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(0));
        // 从当前时间判断触发
        triggerBuilder.startNow();
        // 创建Trigger对象
        return (SimpleTrigger) triggerBuilder.build();
    }


    /**
     * 创建添加定时任务
     */
    public static void addCronJob(QuartzJob quartzJob,String cron) throws Exception {
        String triggerName = "trigger"+quartzJob.getJobName();
        String triggerState = getTriggerState(triggerName, quartzJob.getJobGroup());
        if (Trigger.TriggerState.NONE.name().equals(triggerState)) {
            Class cls = Class.forName(quartzJob.getJobClassName()) ;
            cls.newInstance();
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(quartzJob.getJobName(),
                    quartzJob.getJobGroup())
                    .withDescription(quartzJob.getDescription()).build();
            //jobDetail.getJobDataMap().put("jobMethodName", quartzJob.getJobMethodName());
            // 触发时间点
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, quartzJob.getJobGroup())
                    .startNow().withSchedule(cronScheduleBuilder).build();
            startScheduler(jobDetail, trigger);
        }

    }


    /**
     * 移除定时任务
     */
    public static void removeJob(QuartzJob quartzJob) {
        // 定时任务不存在就不处理
        String triggerName = "trigger"+quartzJob.getJobName();
        String triggerState = getTriggerState(triggerName, quartzJob.getJobGroup());
        if (Trigger.TriggerState.NONE.name().equals(triggerState)) {
            return;
        }
        try {
            Scheduler scheduler = SCHEDULER_FACTORY.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, quartzJob.getJobGroup());
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);

            JobKey jobKey = JobKey.jobKey(quartzJob.getJobName(), quartzJob.getJobGroup());
            // 停止任务
            scheduler.interrupt(jobKey);
            // 删除任务
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            String msg = "停止定时任务失败";
            log.error(msg, e);
           // throw new MyMessageException(GlobalStatusEnum.QUARTZ_ERROR, msg);
        }
    }

    /**
     * 获取触发器状态
     *
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器分组名
     * @return 状态
     * NONE: 不存在
     * NORMAL: 正常
     * PAUSED: 暂停
     * COMPLETE:完成
     * ERROR : 错误
     * BLOCKED : 阻塞
     */
    public static String getTriggerState(String triggerName, String triggerGroupName) {
        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
        try {
            Scheduler scheduler = SCHEDULER_FACTORY.getScheduler();
            Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
            return triggerState.name();
        } catch (SchedulerException e) {
            String msg = "获取触发器状态失败";
            log.error(msg, e);
            //throw new MyMessageException(GlobalStatusEnum.QUARTZ_ERROR, msg);
        }
        return "获取触发器状态失败";
    }


}

4、创建需要执行的Job类

import org.quartz.*;
import org.springframework.scheduling.annotation.Schedules;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 实现序列化接口、防止重启应用出现quartz Couldn't retrieve job because a required class was not found 的问题
 * Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。
 * 其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。
 * @DisallowConcurrentExecution 保证上一个任务执行完后,再去执行下一个任务,这里的任务是同一个任务
 */
@DisallowConcurrentExecution
public class DemoJob implements Job {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        System.out.println("测试方法1");
    }
}

5、编辑QuartzJob实体类

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;
@Data
public class QuartzJob  implements Serializable {

  private long id;
  private String jobName;
  private String jobGroup;
  private String jobClassName;
  private String jobMethodName;
  private String cronExpression;
  private String categoryId;
  private String triggerState;
  private String triggerName;
  private String transLogLevel;
  private String description;
  @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
  private Date createTime;
  @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
  private Date updateTime;

  @Override
  public String toString() {
    return "QuartzJob{" + "id=" + id + ", jobName='" + jobName + '\'' + ", jobGroup='" + jobGroup + '\'' + ", jobClassName='" + jobClassName + '\'' + ", jobMethodName='" + jobMethodName + '\'' + ", cronExpression='" + cronExpression + '\'' + ", categoryId='" + categoryId + '\'' + ", triggerState='" + triggerState + '\'' + ", triggerName='" + triggerName + '\'' + ", transLogLevel='" + transLogLevel + '\'' + ", description='" + description + '\'' + ", createTime=" + createTime + ", updateTime=" + updateTime + '}';
  }
}

6、添加JObJobWController

 

import com.itstyle.quartz.entity.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/job")
public class JobWController {


   @PostMapping("/startJob")
   public Object startJob() throws Exception{
      QuartzJob quartzJob = new QuartzJob();
      quartzJob.setJobName("test01");
      quartzJob.setJobGroup("ChickenJob");
      quartzJob.setDescription("测试任务");
      quartzJob.setJobClassName("com.itstyle.quartz.job.ChickenJob");
      quartzJob.setCronExpression("*/5 * * * * ?");
      quartzJob.setJobMethodName("test1");
      QuartzManage.addCronJob(quartzJob,quartzJob.getCronExpression());
      return "成功";
   }




}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值