欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springboot集成Quartz任务调度

程序员文章站 2024-03-18 17:10:22
...

概述:Quartz是功能强大的开源作业调度库,几乎可以集成到任何Java应用程序中-从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数以万计,数以万计的工作;任务定义为标准Java组件的作业,它们实际上可以执行您可以编写的所有内容。Quartz Scheduler包含许多企业级功能,例如对JTA事务和集群的支持。
Quartz是免费使用的,并根据Apache 2.0许可获得许可。

以上是在Quartz官网上复制的。废话不多说,执行上代码。

提前准备工作,自己到quartz官网上下载源码,里面带有不同数据库版本的脚本进行初始化sql脚本
,我这快使用的是quartz-2.3.0-SNAPSHOT版本,数据库使用的postgresql 11

脚本路径为:quartz-2.3.0-distribution.tar\quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore

这块根据自己使用的数据库进行选择即可。

1、pom代码

<!--quartz定时调度依赖-->
  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-quartz</artifactId>
   </dependency>

版本是根据springboot框架自动获取的,我这块用的是2.0.4.RELEASE

2、Quartz配置类

import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

import javax.sql.DataSource;

/**
 * Quartz任务调度配置器
 */
@Configuration
@EnableScheduling
public class QuartzConfiguration {
    /**
     * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory
     * 实现任务实例化方式
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
            ApplicationContextAware {

        private transient AutowireCapableBeanFactory beanFactory;

        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }

        /**
         * 将job实例交给spring ioc托管
         * 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
         *
         * @param bundle
         * @return
         * @throws Exception
         */
        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            /**
             * 将job实例交付给spring ioc
             */
            beanFactory.autowireBean(job);
            return job;
        }
    }

    /**
     * 配置任务工厂实例
     *
     * @return
     */
    @Bean
    public JobFactory jobFactory() {
        /**
         * 采用自定义任务工厂 整合spring实例来完成构建任务*/
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        return jobFactory;
    }

    /**
     * 配置任务调度器
     * 使用项目数据源作为quartz数据源
     *
     * @param jobFactory 自定义配置任务工厂
     * @param dataSource 数据源实例
     * @return
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy", autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        //将spring管理job自定义工厂交由调度器维护
        schedulerFactoryBean.setJobFactory(jobFactory);
        //设置覆盖已存在的任务
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        //项目启动完成后,等待2秒后开始执行调度器初始化
        schedulerFactoryBean.setStartupDelay(2);
        //设置调度器自动运行
        schedulerFactoryBean.setAutoStartup(true);
        //设置数据源,使用与项目统一数据源
        schedulerFactoryBean.setDataSource(dataSource);
        //设置上下文spring bean name
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
        //设置配置文件位置
        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        return schedulerFactoryBean;
    }
}

3、Quartz配置文件quartz.properties

# 在集群中每个实例都必须有一个唯一的instanceId,但是应该有一个相同的instanceName【默认“QuartzScheduler”】
org.quartz.scheduler.instanceName = schedulerFactoryBean
# 只有在”org.quartz.scheduler.instanceId”设置为”AUTO”的时候才使用该属性设置
# 默认情况下,“org.quartz.simpl.SimpleInstanceIdGenerator”是基于instanceId和时间戳来自动生成的
org.quartz.scheduler.instanceId = AUTO
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#驱动程序代表理解不同数据库系统的特定方言,许多数据库使用StdJDBCDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
#数据库中表的前缀
org.quartz.jobStore.tablePrefix = QRTZ_
# 为了指示JDBCJobStore所有的JobDataMaps中的值都是字符串,并且能以“名字-值”对的方式存储而不是以复杂对象的序列化形式存储在BLOB字段中,应该设置为true(缺省方式)
org.quartz.jobStore.useProperties = false
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
# 并发个数
org.quartz.threadPool.threadCount = 10
# 优先级
org.quartz.threadPool.threadPriority = 5

基本上Quartz的配置完成,下面开始些正在的实现操作。

4、TestController实现

package com.joe.oauth.quartz.controller;

import com.joe.oauth.quartz.domin.TaskScheduleVo;
import com.joe.oauth.quartz.job.TestJob1;
import com.joe.oauth.quartz.service.QuartzService;
import com.joe.oauth.quartz.util.CronUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Calendar;

@RestController
public class TestController {

    @Autowired
    private QuartzService quartzService;
    @RequestMapping("/addjob")
    public void startJob(String jobName) {
        TaskScheduleVo taskScheduleVo = new TaskScheduleVo();
        Calendar now = Calendar.getInstance();
        taskScheduleVo.setJobType(1);
        taskScheduleVo.setHour(now.get(Calendar.HOUR_OF_DAY));
        taskScheduleVo.setMinute(now.get(Calendar.MINUTE)+1);//分
        taskScheduleVo.setSecond(0);//秒
        //组装cron表达式
        String cron = CronUtil.createCronExpression(taskScheduleVo);
        quartzService.addJob(TestJob1.class, jobName, "test", "0/10 * * * * ?");
    }
    
    @RequestMapping("/updatejob")
    public void updatejob(String jobName) {
            quartzService.updateJob(jobName, "test", "0/10 * * * * ?");
    }
    
    @RequestMapping("/deletejob")
    public void deletejob(String jobName) {
            quartzService.deleteJob(jobName, "test");
    }
    
    @RequestMapping("/pauseJob")
    public void pauseJob(String jobName) {
            quartzService.pauseJob(jobName, "test");
    }
    
    @RequestMapping("/resumeJob")
    public void resumeJob(String jobName) {
            quartzService.resumeJob(jobName, "test");
    }
    
    @RequestMapping("/queryAllJob")
    public Object queryAllJob() {
            return quartzService.queryAllJob();
    }
    

    @RequestMapping("/queryRunJob")
    public Object queryRunJob() {
            return quartzService.queryRunJob();
    }
}

5、Job的业务层

package com.joe.oauth.quartz.job;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.Date;

@PersistJobDataAfterExecution //参数持久化,这块暂时没有传入参数,加上该属性不影响
@DisallowConcurrentExecution// 不允许并发执行
public class TestJob1 extends QuartzJobBean {

    @Override
    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {
        System.out.println(new Date() + "    job执行");
    }

}

6、QuartzService实现

package com.joe.oauth.quartz.service;

import org.quartz.*;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

@Service
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<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, int jobTime,
            int jobTimes) {
        try {
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
                    .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<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobTime) {
        try {
            // 创建jobDetail实例,绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定job类
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
                    .build();
            // 定义调度触发规则
            // 使用cornTrigger规则
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)// 触发器key
                    .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).startNow().build();
            // 把作业和触发器注册到任务调度中
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 修改 一个job的 时间表达式
     * 
     * @param jobName
     * @param jobGroupName
     * @param jobTime
     */
    public void updateJob(String jobName, String jobGroupName, String jobTime) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
            // 重启触发器
            scheduler.rescheduleJob(triggerKey, trigger);
        } 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
     * @param jobGroupName
     */
    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
     * @param 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
     * @param jobGroupName
     */
    public void runAJobNow(String jobName, String jobGroupName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取所有计划中的任务列表
     * 
     * @return
     */
    public List<Map<String, Object>> queryAllJob() {
        List<Map<String, Object>> jobList = null;
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            jobList = new ArrayList<Map<String, Object>>();
            for (JobKey jobKey : jobKeys) {
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    Map<String, Object> 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
     */
    public List<Map<String, Object>> queryRunJob() {
        List<Map<String, Object>> jobList = null;
        try {
            List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
            jobList = new ArrayList<Map<String, Object>>(executingJobs.size());
            for (JobExecutionContext executingJob : executingJobs) {
                Map<String, Object> map = new HashMap<String, Object>();
                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;
    }

}

7、CronUtil工具类

package com.joe.oauth.quartz.util;

import com.joe.oauth.quartz.domin.TaskScheduleVo;

public class CronUtil {

    /**
     *
     *方法摘要:构建Cron表达式
     *@param  taskScheduleVo
     *@return String
     */
    public static String createCronExpression(TaskScheduleVo taskScheduleVo){
        StringBuffer cronExp = new StringBuffer("");

        if(null == taskScheduleVo.getJobType()) {
            System.out.println("执行周期未配置" );//执行周期未配置
        }

        if (null != taskScheduleVo.getSecond()
                && null == taskScheduleVo.getMinute()
                && null == taskScheduleVo.getHour()){
            //每隔几秒
            if (taskScheduleVo.getJobType().intValue() == 0) {
                cronExp.append("0/").append(taskScheduleVo.getSecond());
                cronExp.append(" ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("?");
            }

        }

        if (null != taskScheduleVo.getSecond()
                && null != taskScheduleVo.getMinute()
                && null == taskScheduleVo.getHour()){
            //每隔几分钟
            if (taskScheduleVo.getJobType().intValue() == 4) {
                cronExp.append("* ");
                cronExp.append("0/").append(taskScheduleVo.getMinute());
                cronExp.append(" ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("?");
            }

        }

        if (null != taskScheduleVo.getSecond()
                && null != taskScheduleVo.getMinute()
                && null != taskScheduleVo.getHour()) {
            //秒
            cronExp.append(taskScheduleVo.getSecond()).append(" ");
            //分
            cronExp.append(taskScheduleVo.getMinute()).append(" ");
            //小时
            cronExp.append(taskScheduleVo.getHour()).append(" ");

            //每天
            if(taskScheduleVo.getJobType().intValue() == 1){
                cronExp.append("* ");//日
                cronExp.append("* ");//月
                cronExp.append("?");//周
            }

            //按每周
            else if(taskScheduleVo.getJobType().intValue() == 3){
                //一个月中第几天
                cronExp.append("? ");
                //月份
                cronExp.append("* ");
                //周
                Integer[] weeks = taskScheduleVo.getDayOfWeeks();
                for(int i = 0; i < weeks.length; i++){
                    if(i == 0){
                        cronExp.append(weeks[i]);
                    } else{
                        cronExp.append(",").append(weeks[i]);
                    }
                }

            }

            //按每月
            else if(taskScheduleVo.getJobType().intValue() == 2){
                //一个月中的哪几天
                Integer[] days = taskScheduleVo.getDayOfMonths();
                for(int i = 0; i < days.length; i++){
                    if(i == 0){
                        cronExp.append(days[i]);
                    } else{
                        cronExp.append(",").append(days[i]);
                    }
                }
                //月份
                cronExp.append(" * ");
                //周
                cronExp.append("?");
            }

        }
        else {
            System.out.println("时或分或秒参数未配置" );//时或分或秒参数未配置
        }
        return cronExp.toString();
    }

    /**
     *
     *方法摘要:生成计划的详细描述
     *@param  taskScheduleVo
     *@return String
     */
    public static String createDescription(TaskScheduleVo taskScheduleVo){
        StringBuffer description = new StringBuffer("");
        //计划执行开始时间
//      Date startTime = taskScheduleVo.getScheduleStartTime();

        if (null != taskScheduleVo.getSecond()
                && null != taskScheduleVo.getMinute()
                && null != taskScheduleVo.getHour()) {
            //按每天
            if(taskScheduleVo.getJobType().intValue() == 1){
                description.append("每天");
                description.append(taskScheduleVo.getHour()).append("时");
                description.append(taskScheduleVo.getMinute()).append("分");
                description.append(taskScheduleVo.getSecond()).append("秒");
                description.append("执行");
            }

            //按每周
            else if(taskScheduleVo.getJobType().intValue() == 3){
                if(taskScheduleVo.getDayOfWeeks() != null && taskScheduleVo.getDayOfWeeks().length > 0) {
                    String days = "";
                    for(int i : taskScheduleVo.getDayOfWeeks()) {
                        days += "周" + i;
                    }
                    description.append("每周的").append(days).append(" ");
                }
                if (null != taskScheduleVo.getSecond()
                        && null != taskScheduleVo.getMinute()
                        && null != taskScheduleVo.getHour()) {
                    description.append(",");
                    description.append(taskScheduleVo.getHour()).append("时");
                    description.append(taskScheduleVo.getMinute()).append("分");
                    description.append(taskScheduleVo.getSecond()).append("秒");
                }
                description.append("执行");
            }

            //按每月
            else if(taskScheduleVo.getJobType().intValue() == 2){
                //选择月份
                if(taskScheduleVo.getDayOfMonths() != null && taskScheduleVo.getDayOfMonths().length > 0) {
                    String days = "";
                    for(int i : taskScheduleVo.getDayOfMonths()) {
                        days += i + "号";
                    }
                    description.append("每月的").append(days).append(" ");
                }
                description.append(taskScheduleVo.getHour()).append("时");
                description.append(taskScheduleVo.getMinute()).append("分");
                description.append(taskScheduleVo.getSecond()).append("秒");
                description.append("执行");
            }

        }
        return description.toString();
    }

    //参考例子
    public static void main(String[] args) {
        //执行时间:每天的12时12分12秒 start
        TaskScheduleVo taskScheduleVo = new TaskScheduleVo();

        taskScheduleVo.setJobType(0);//按每秒
        taskScheduleVo.setSecond(30);
        String cronExp = createCronExpression(taskScheduleVo);
        System.out.println(cronExp);

        taskScheduleVo.setJobType(4);//按每分钟
        taskScheduleVo.setMinute(8);
        String cronExpp = createCronExpression(taskScheduleVo);
        System.out.println(cronExpp);

        taskScheduleVo.setJobType(1);//按每天
        Integer hour = 12; //时
        Integer minute = 12; //分
        Integer second = 12; //秒
        taskScheduleVo.setHour(hour);
        taskScheduleVo.setMinute(minute);
        taskScheduleVo.setSecond(second);
        String cropExp = createCronExpression(taskScheduleVo);
        System.out.println(cropExp + ":" + createDescription(taskScheduleVo));
        //执行时间:每天的12时12分12秒 end

        taskScheduleVo.setJobType(3);//每周的哪几天执行
        Integer[] dayOfWeeks = new Integer[3];
        dayOfWeeks[0] = 1;
        dayOfWeeks[1] = 2;
        dayOfWeeks[2] = 3;
        taskScheduleVo.setDayOfWeeks(dayOfWeeks);
        cropExp = createCronExpression(taskScheduleVo);
        System.out.println(cropExp + ":" + createDescription(taskScheduleVo));

        taskScheduleVo.setJobType(2);//每月的哪几天执行
        Integer[] dayOfMonths = new Integer[3];
        dayOfMonths[0] = 1;
        dayOfMonths[1] = 21;
        dayOfMonths[2] = 13;
        taskScheduleVo.setDayOfMonths(dayOfMonths);
        cropExp = createCronExpression(taskScheduleVo);
        System.out.println(cropExp + ":" + createDescription(taskScheduleVo));

    }

}

8、Cron时间实体

package com.joe.oauth.quartz.domin;

import lombok.Data;

@Data
public class TaskScheduleVo {

    /**
     * 所选作业类型:
     * 0  -> 每秒
     * 4  -> 每分
     * 1  -> 每天
     * 3  -> 每周
     * 2  -> 每月
     */
    Integer jobType;

    /**月*/
    Integer[] dayOfMonths;

    /**天*/
    Integer[] dayOfWeeks;

    /**秒  */
    Integer second;

    /**分  */
    Integer minute;

    /**时  */
    Integer hour;

}

9、执行结果如下:

springboot集成Quartz任务调度
这块我设置的间隔10秒执行异常任务。
springboot集成Quartz任务调度