SpringBoot集成quartz实现定时任务(可修改cron表达式和传入参数)

第一步创建SpringBoot项目的过程我就不在演示了!自己找找教程吧!

第二步,导入依赖:

 
        
            org.springframework.boot
            spring-boot-starter-quartz
        
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.quartz-scheduler
            quartz
            2.3.0
        

        
            org.springframework
            spring-context-support
            5.3.8
        

        
            org.springframework.boot
            spring-boot-starter-jdbc
        

        
            mysql
            mysql-connector-java
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.2
        
        
            org.projectlombok
            lombok
        

第三步,启动类上加@EnableScheduling开启定时任务

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

}

第四步,创建QuartzService类

package com.example.quartz3.job;
 
import java.util.*;
 
import javax.annotation.PostConstruct;
 
import lombok.extern.log4j.Log4j2;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.QuartzJobBean;
 
/**
 * 调度service
 */
@Configuration
@EnableScheduling
@Log4j2
public class QuartzService {
    @Autowired
    private Scheduler scheduler;
 
    @PostConstruct
    public void startScheduler() {
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 增加一个job
     *
     * @param jobClass     任务实现类
     * @param jobName      任务名称
     * @param jobGroupName 任务组名
     * @param jobTime      时间表达式 (这是每隔多少秒为一次任务)
     * @param jobTimes     运行的次数 (<0:表示不限次数)
     */
    public void addJob(Class jobClass, String jobName, String jobGroupName, int jobTime,
                       int jobTimes) {
        try {
            // 任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .build();
            // 使用simpleTrigger规则
            Trigger trigger = null;
            if (jobTimes < 0) {
                trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                        .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
                        .startNow().build();
            } else {
                trigger = TriggerBuilder
                        .newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
                                .repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
                        .startNow().build();
            }
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 增加一个job
     *
     * @param jobClass     任务实现类
     * @param jobName      任务名称
     * @param jobGroupName 任务组名
     * @param jobTime      时间表达式 (如:0/5 * * * * ? )
     */
    public void addJob(Class jobClass, String jobName, String jobGroupName, String jobTime,Integer userId) {
        try {
            // 创建jobDetail实例,绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定job类
            // 任务名称和组构成任务key
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)
                    .usingJobData("userId",userId)//可以使用usingJobData添加传入的参数,辅助后面job任务的业务实现
                    .build();
            // 定义调度触发规则
            // 使用cornTrigger规则
            // 触发器key
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
                    .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime).inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))).startNow().build();
            // 把作业和触发器注册到任务调度中
            scheduler.scheduleJob(jobDetail, trigger);
            if(!scheduler.isShutdown()){
                scheduler.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 修改 一个job的 时间表达式
     */
    public void updateJob(String jobName, String jobGroupName, String jobTime) {
        try {
            log.warn("Start update job ,job name is {}, jobCron is {}", jobName, jobTime);
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime).inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))).build();
            // 重启触发器
            scheduler.rescheduleJob(triggerKey, trigger);
            log.warn("finish update job!");
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 删除任务一个job
     *
     * @param jobName      任务名称
     * @param jobGroupName 任务组名
     */
    public void deleteJob(String jobName, String jobGroupName) {
        try {
            scheduler.deleteJob(new JobKey(jobName, jobGroupName));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 暂停一个job
     *
     * @param jobName jobName
     * @param jobGroupName jobName
     */
    public void pauseJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 恢复一个job
     *
     * @param jobName jobName
     * @param jobGroupName jobGroupName
     */
    public void resumeJob(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 立即执行一个job
     *
     * @param jobName jobName
     * @param jobGroupName jobGroupName
     */
    public void runAJobNow(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 获取所有计划中的任务列表
     *
     * @return List
     */
    public List> queryAllJob() {
        List> jobList = null;
        try {
            GroupMatcher matcher = GroupMatcher.anyJobGroup();
            Set jobKeys = scheduler.getJobKeys(matcher);
            jobList = new ArrayList>();
            for (JobKey jobKey : jobKeys) {
                List triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Map map = new HashMap<>();
                    map.put("jobName", jobKey.getName());
                    map.put("jobGroupName", jobKey.getGroup());
                    map.put("description", "触发器:" + trigger.getKey());
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    map.put("jobStatus", triggerState.name());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        map.put("jobTime", cronExpression);
                    }
                    jobList.add(map);
                }
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }
 
    /**
     * 获取所有正在运行的job
     *
     * @return List
     */
    public List> queryRunJob() {
        List> jobList = null;
        try {
            List executingJobs = scheduler.getCurrentlyExecutingJobs();
            jobList = new ArrayList>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                Map map = new HashMap();
                JobDetail jobDetail = executingJob.getJobDetail();
                JobKey jobKey = jobDetail.getKey();
                Trigger trigger = executingJob.getTrigger();
                map.put("jobName", jobKey.getName());
                map.put("jobGroupName", jobKey.getGroup());
                map.put("description", "触发器:" + trigger.getKey());
                Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                map.put("jobStatus", triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    map.put("jobTime", cronExpression);
                }
                jobList.add(map);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return jobList;
    }
 
}

第五步,创建自己的Job类实现自己的业务逻辑

package com.example.quartz3.job;
 
import com.example.quartz3.domain.User;
import com.example.quartz3.mapper.UserMapper;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 定时全量备份job
 */
@Component
@Log4j2
public class SomThingTimeJob extends QuartzJobBean {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private QuartzService quartzService;
 
    @SneakyThrows
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.warn("start SomThingTimeJob !! ");
        //写自己要实现的业务逻辑
        Integer userId = (Integer) context.getJobDetail().getJobDataMap().get("userId");
        //可以使用getJobDetail的getJobDataMap方法获取传入的其他参数辅助自己的业务实现
        User users = userMapper.selectUserById(userId);
        System.out.println(new Date()+"用户姓名"+users.getUserName());

        log.warn("finish SomThingTimeJob !! ");
    }
}

第六步,Cron表达式转换工具类

package com.example.quartz3.utils;

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

/**
 * @author 一个达不刘
 * cron表达式生成工具类
 *
 */
public class CronUtil {

    /**
     * 生成指定格式日期字符
     *
     * @param date       日期
     * @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss
     * @return formatTimeStr
     */
    public static String formatDateByPattern(Date date, String dateFormat) {
        dateFormat = dateFormat == null ? "yyyy-MM-dd HH:mm:ss" : dateFormat;
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return date != null ? sdf.format(date) : null;
    }

    /**
     * 生成cron表达式 ss mm HH dd MM ? yyyy
     * convert Date to cron ,eg.  "0 06 10 15 1 ? 2014"
     *
     * @param date : 时间点
     */
    public static String getCron(Date date) {
        String dateFormat = "ss mm HH dd MM ? yyyy";
        return formatDateByPattern(date, dateFormat);
    }

    /**
     * 生成cron表达式 ss mm HH dd MM ?
     * convert Date to cron ,eg.  "0 06 10 15 1 ?"
     *
     * @param date : 时间点
     * @param type : 类型 日/周/月
     */
    public static String getLoopCron(Date date, String type, Integer week, Integer day) {
        String dateFormat = "ss mm HH";
        //  dd MM ?
        String cron = formatDateByPattern(date, dateFormat);
        switch (type) {
            case "Day":
                return cron + " * * ?";
            case "Week":
                return cron + " ? * " + getCurrentWeek(week);
            case "Month":
                return cron + " " + day + " * ?";
            default:
                return "false";
        }
    }


    /**
     * 获取当前星期的字符 MON TUE WED THU FRI SAT SUN
     *
     * @param week : 周 1 2 3 4 5 6 7
     * @return 星期字符
     */
    public static String getCurrentWeek(Integer week) {
        String[] weeks = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
        return weeks[week - 1];
    }
    public static void main(String[] args) {
        Date date = new Date();

        //String dateFormat = "ss mm HH dd MM ? yyyy";
        //String cron = formatDateByPattern(date, dateFormat);
        //System.out.println("原始:" + cron);
        //
        //String day = formatDateByPattern(date, "ss mm HH");
        //System.out.println("日报:" + day + " * * ?");
        //
         0 15 10 ? * MON 每周一上午10点15分
         动参为 周
        //String week = formatDateByPattern(date, "ss mm HH");
        //System.out.println("周报:" + week + " ? * MON");
        //
         0 15 9 10 * ? 每月10号9点15分
         动参为 号
        //String month = formatDateByPattern(date, "ss mm HH");
        //System.out.println("月报:" + month + " 10 * ?");
    }
}

第七步,创建字符串转换成类的转换器

package com.example.quartz3.utils;

import org.springframework.scheduling.quartz.QuartzJobBean;

/**
 * @author 一个达不刘
 * @date 2023/3/20 18:34
 */
public class ClassUtil {
    @SuppressWarnings("unchecked")
    public static Class getClass(String classname) throws Exception {
        Class class1 = Class.forName(classname);
        return (Class) class1;
    }
}

为什么使用这个转换器的原因是创建job的时候

public void addJob(Class jobClass, String jobName, String jobGroupName, int jobTime,int jobTimes)

jobClass是一个.class的对象,但是传入的参数不可能是一个.class的对象,所以需要一个转换器

第八步,创建controller控制层

package com.example.quartz3.controller;


import com.example.quartz3.job.QuartzService;
import com.example.quartz3.utils.ClassUtil;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;


/**
 * @author 钟于一个达不刘
 */
@RestController
@RequestMapping(value = "/job")
public class JobController {

    @Autowired
    private QuartzService quartzService;




    /**
     * @param jobClassName
     * @param jobGroupName
     * @param cronExpression
     * @throws Exception
     */
    @PostMapping(value = "/addjob")
    public void addjob(@RequestParam(value = "jobClassName") String jobClassName,
                       @RequestParam(value = "jobGroupName") String jobGroupName,
                       @RequestParam(value = "cronExpression") String cronExpression,
                       @RequestParam("userId") Integer userId) throws Exception {
        quartzService.addJob(ClassUtil.getClass(jobClassName), jobClassName, jobGroupName, cronExpression,userId);
    }

    /**
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "/pausejob")
    public void pausejob(@RequestParam(value = "jobClassName") String jobClassName,
                         @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        quartzService.pauseJob(jobClassName, jobGroupName);
    }

    /**
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "/resumejob")
    public void resumejob(@RequestParam(value = "jobClassName") String jobClassName,
                          @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        quartzService.resumeJob(jobClassName, jobGroupName);
    }


    /**
     * @param jobClassName
     * @param jobGroupName
     * @throws Exception
     */
    @PostMapping(value = "/deletejob")
    public void deletejob(@RequestParam(value = "jobClassName") String jobClassName,
                          @RequestParam(value = "jobGroupName") String jobGroupName) throws Exception {
        quartzService.deleteJob(jobClassName, jobGroupName);
    }

}

第九步,创建User实体类

package com.example.quartz3.mapper;

import com.example.quartz3.domain.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author 一个达不刘
 * @date 2023/3/19 19:28
 */
@Mapper
public interface UserMapper {
    List selectList(Object o);

    int insertUser(User user);

    User selectUserById(int id);
}

第十步,创建mapper文件进行测试

package com.example.quartz3.mapper;

import com.example.quartz3.domain.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author 一个达不刘
 * @date 2023/3/19 19:28
 */
@Mapper
public interface UserMapper {
    List selectList(Object o);

    int insertUser(User user);

    User selectUserById(int id);
}

第十一步,测试

SpringBoot集成quartz实现定时任务(可修改cron表达式和传入参数)_第1张图片

 SpringBoot集成quartz实现定时任务(可修改cron表达式和传入参数)_第2张图片

有志向于IT技术的小伙伴,或者想要一些IT技术的资料,可以来QQ群获取:526519295

你可能感兴趣的:(spring,boot,mybatis,java,quartz)