Quartz组件的搭建及实现任务调度demo

1.基本环境配置

复制代码
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version></dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.3</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.3</version>
</dependency>
复制代码

2.demo的封装及使用

2.1 TaskJob实体类

复制代码
@Data
@ApiModel(value = "调度任务表")
public class TaskJob  extends BaseEntity {
    @ApiModelProperty(value="定时任务ID")
    private Long jobId;
    @ApiModelProperty(value="定时任务组")
    private String jobGroup;
    @ApiModelProperty(value="定时任务名称")
    private String jobName;
    @ApiModelProperty(value="任务开始时间")
    private Date startTime;
    @ApiModelProperty(value="任务结束时间")
    private Date endTime;
    @ApiModelProperty(value="cron表达式")
    private String cronExpression;
    @ApiModelProperty(value="任务执行时调用哪个类的方法 包名+类名 例如 com.nbs.RunJob")
    private String jobClassName;
    @ApiModelProperty(value="参数")
    private String jsonParam;
    @ApiModelProperty(value="任务状态 0.正运行 1.已停止")
    private Integer jobStatus;

    @Override
    public HashMap<String, String> getColumnMap(){return columnMap;}
    @Override
    public HashMap<String, String> getTableMap(){return tableMap;}
    @Override
    public HashMap<String, String> getSqlMap(){return sqlMap;}
    private static final HashMap<String, String> columnMap = new HashMap(){{
        put("任务ID", "t.jobId");
        put("任务组", "t.jobGroup");
        put("任务名称", "t.jobName");
        put("任务开始时间", "t.startTime");
        put("任务结束时间", "t.endTime");
        put("cron表达式", "t.cronExpression");
        put("调用类", "t.jobClassName");
        put("任务状态", "t.jobStatus");
        put("备注", "t.remark");
        put("创建时间", "t.createTime");
        put("创建人", "t.createUserName");
        put("编辑时间", "t.updateTime");
        put("编辑人", "t.updateUserName");
        put("是否删除","t.delFlag");
    }};
    private final static HashMap<String, String> tableMap = new HashMap(){{
        put("list","TaskJob  as t");
        put("dropList","TaskJob as t");
    }};
    private final static HashMap<String, String> sqlMap = new HashMap(){{
        put("任务状态","case when t.jobStatus=0 then '正运行' else '启用' 已停止");
    }};
}
复制代码

2.2 QuartzUtil工具类

复制代码
public class QuartzUtil {
    /**
     * 创建任务
     *
     * @param taskJob
     * @throws SchedulerException
     * @throws ClassNotFoundException
     */
    public ResultModel createTaskJob(Scheduler scheduler,TaskJob taskJob) throws SchedulerException, ClassNotFoundException {
        //任务执行类
        Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(taskJob.getJobClassName());
        // 构建job信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(taskJob.getJobName(), taskJob.getJobGroup()).build();
        if (StringUtil.isNotEmpty(taskJob.getJsonParam())) {
            JSONObject jsonObject = JSON.parseObject(taskJob.getJsonParam());
            for (String key : jsonObject.keySet()) {
                jobDetail.getJobDataMap().put(key, jsonObject.get(key));
            }
        }
        TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger().withIdentity(taskJob.getJobName(), taskJob.getJobGroup());
        triggerBuilder.usingJobData(jobDetail.getJobDataMap());
        if (StringUtil.isNotEmpty(taskJob.getCronExpression())) {
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(taskJob.getCronExpression());
            // 按新的cronExpression表达式构建一个新的trigger
            triggerBuilder.withSchedule(scheduleBuilder);
        } else {
            throw new ConcurrentException(new ResultModel(false, ResultModel.DATA_ERROR, "定时器启动失败,未设置时间表达式且未设置间隔时间"));
        }


        if (taskJob.getStartTime() != null && taskJob.getStartTime().getTime() > new Date().getTime()) {
            triggerBuilder.startAt(taskJob.getStartTime());
        }
        if (taskJob.getEndTime() != null) {
            if (taskJob.getEndTime().getTime() <= new Date().getTime()) {
                //结束时间早于现在,直接不用执行了
                return new ResultModel(false, ResultModel.DATA_ERROR, "定时器启动失败,结束时间早于开始时间!");
            }
            triggerBuilder.endAt(taskJob.getEndTime());
        }
        scheduler.scheduleJob(jobDetail, triggerBuilder.build());
        return new ResultModel(true, ResultModel.SUCCESS, "启动成功!");
    }



    /**
     * 获取任务状态
     *
     * @param jobName
     * @param jobGroup
     * @return
     * @throws SchedulerException
     */
    public JobInfo getJobInfo(Scheduler scheduler,String jobName, String jobGroup) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey(jobName, jobGroup);
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        JobInfo info = new JobInfo();
        info.setJobName(jobName);
        info.setJobGroup(jobGroup);
        info.setCronExpression(cronTrigger.getCronExpression());
        info.setJobStatus(scheduler.getTriggerState(triggerKey).name());
        return info;
    }


    /**
     * 删除任务
     *
     * @param jobName
     * @param jobGroup
     * @throws SchedulerException
     */
    public ResultModel deleteJob(Scheduler scheduler,String jobName, String jobGroup) throws SchedulerException {
        JobKey jobKey = new JobKey(jobName, jobGroup);
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        if (jobDetail != null) {
            scheduler.deleteJob(jobKey);
        }
        return new ResultModel(true, ResultModel.SUCCESS, "启动成功!");
    }


    public static TriggerKey getTriggerKey(String jobName, String jobGroup) {
        return TriggerKey.triggerKey(jobName, jobGroup);
    }

    public ResultModel  saveTaskJob(Scheduler scheduler,TaskJob taskJob) {
        TriggerKey triggerKey=TriggerKey.triggerKey(taskJob.getJobName(),taskJob.getJobGroup());
        if (triggerKey==null){
            try {
                return createTaskJob(scheduler, taskJob);
            }catch (Exception ex){
                return new ResultModel(false,ResultModel.CHECK_ERROR,ex.getMessage());
            }
        } else {
            try {
                return updateTaskJob(scheduler,taskJob);
            }catch (Exception ex){
                return new ResultModel(false,ResultModel.CHECK_ERROR,ex.getMessage());
            }
        }
    }


    /**
     * 更新任务
     * @throws SchedulerException
     */
    public ResultModel  updateTaskJob(Scheduler scheduler,TaskJob taskJob) throws SchedulerException {
        TriggerKey triggerKey = new TriggerKey(taskJob.getJobName(),taskJob.getJobGroup());
        //表达式调度构建器
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(taskJob.getCronExpression());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        if (StringUtil.isNotEmpty(taskJob.getJsonParam())) {
            JSONObject jsonObject = JSON.parseObject(taskJob.getJsonParam());
            for (String key : jsonObject.keySet()) {
                trigger.getJobDataMap().put(key, jsonObject.get(key));
            }
        }

        if ((taskJob.getStartTime()!=null) && (taskJob.getEndTime()!=null)){
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).startAt(taskJob.getStartTime()).endAt(taskJob.getEndTime()).withSchedule(scheduleBuilder).build();
        } else {
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
        }

        //按新的trigger重新设置job执行
        scheduler.rescheduleJob(triggerKey, trigger);
        return new ResultModel(true, ResultModel.SUCCESS, "启动成功!");
    }
}
复制代码

2.3 TaskJobServiceImpl实现类调用QuartzUtil方法

(1)、新增调度任务调用创建调度方法

try{
    return quartzUtil.createTaskJob(scheduler, entity);
}catch (Exception ex){
    throw new ConcurrentException(new ResultModel(false, ResultModel.BUSINESS_ERROR, "添加调度任务失败,原因:"+ex.getMessage() ));
}

(2)、修改调度任务调用saveTaskJob调度方法

复制代码
try{
    if (entity.getJobStatus()==0) { //判断正在启用的调度任务方法
        return quartzUtil.saveTaskJob(scheduler, entity);
    } else {
        return new ResultModel(true, ResultModel.SUCCESS, "成功!");
    }

}catch (Exception ex){
    throw new ConcurrentException(new ResultModel(false, ResultModel.BUSINESS_ERROR, "添加调度任务失败,原因:"+ex.getMessage() ));
}
复制代码

(3)、删除调度任务调用deleteJob调度方法

try{
    return quartzUtil.deleteJob(scheduler, job.getJobName(),job.getJobGroup());
}catch (Exception ex){
    throw new ConcurrentException(new ResultModel(false, ResultModel.BUSINESS_ERROR, "添加调度任务失败,原因:"+ex.getMessage() ));
}

(4)、启用所有调度任务

复制代码
List<TaskJob> jobs=taskJobDAO.selectByParams(null);

for (TaskJob job:jobs){
    try {
       ResultModel rm= quartzUtil.createTaskJob(scheduler, job);
       if (rm.isSuccess()){
           taskJobDAO.updateJobStatus(job.getJobId(),0);
       } else {
           taskJobDAO.updateJobStatus(job.getJobId(),1);
       }
    }catch (Exception ex)
    {
        System.out.println("启动所有任务,失败原因:"+ex.getMessage());
    }
}
复制代码

5)、启停调度任务

if  (jobStatus==0){
    quartzUtil.createTaskJob(scheduler, job);
} else {
    quartzUtil.deleteJob(scheduler, job.getJobName(),job.getJobGroup());
}

3.调度任务web页面创建

4.OrderPrintTestJob业务类

复制代码
@Slf4j
//保持单例不并发(集群会出现重复执行任务问题)
@DisallowConcurrentExecution
public class OrderPrintTestJob implements Job, Serializable {

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        JobDataMap dataMap = jobExecutionContext.getTrigger().getJobDataMap();
        String  myName = dataMap.get("myName").toString();
        System.out.println("*******************这是我要打印的内容[OrderPrintTestJob],参数:"+myName+",时间:"+DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss")  +"*******************");
    }
}
复制代码

5.配置类开启计划任务的支持

@EnableScheduling
public class NbsBusinessCenterApplication {
    public static void main(String[] args) {
        SpringApplication.run(NbsBusinessCenterApplication.class, args);
    }
}

 

 

posted @   司徒翘臀  阅读(148)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示