美文网首页
Springboot 2.1.2 整合quartz 2.3.0

Springboot 2.1.2 整合quartz 2.3.0

作者: Lanjerry | 来源:发表于2019-01-29 14:11 被阅读0次
    说明:
    核心框架: SpringBoot 2.1.2
    任务调度框架: Quartz 2.3.0
    持久层框架: mybatis-plus 3.0.7
    数据库:mysql 8.0.12
    1.项目目录结构
    image.png
    2.数据库表结构
    DROP TABLE IF EXISTS `schedule_job`;
    CREATE TABLE `schedule_job`  (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '任务id',
      `job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务名称',
      `cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表达式',
      `bean_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '服务名称',
      `method_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '方法名称',
      `status` int(1) NOT NULL DEFAULT 1 COMMENT '状态 1.启动 2.暂停',
      `delete_flag` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否删除 0.否 1.是',
      `creator_id` int(11) NULL DEFAULT NULL COMMENT '创建人id',
      `creator_name` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
      `created_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
      `updated_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    SET FOREIGN_KEY_CHECKS = 1;
    
    3.pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.2.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <!--Web-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--Quartz-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>
            <!--Mysql驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.11</version>
            </dependency>
            <!--Mybatis-Plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.0.7</version>
            </dependency>
            <!--Test-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    4.application.yml
    server:
      port: 8080
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/lanjerry?useUnicode=yes&characterEncoding=UTF8&useSSL=false&serverTimezone=CTT&allowMultiQueries=true
        username: root
        password: 123456
        hikari:
          max-lifetime: 1765000
          maximum-pool-size: 15
      aop:
        proxy-target-class: true
        auto: true
    
    #mybatis-plus配置
    mybatis-plus:
      global-config:
        db-config:
          field-strategy: not_empty
          id-type: auto
          db-type: mysql
          logic-delete-value: 1
          logic-not-delete-value: 0
        banner: false
      mapper-locations: classpath:/mapper/*Mapper.xml
      type-aliases-package: com.example.demo.domain
    
    5.Quartz配置:QuartzConfig.class
    @Configuration
    public class QuartzConfig {
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(){
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            schedulerFactoryBean.setOverwriteExistingJobs(true);//覆盖已存在的任务
            schedulerFactoryBean.setStartupDelay(60);//延时60秒启动定时任务,避免系统未完全启动却开始执行定时任务的情况
            return schedulerFactoryBean;
        }
    
        // 创建schedule
        @Bean(name = "scheduler")
        public Scheduler scheduler() {
            return schedulerFactoryBean().getScheduler();
        }
    }
    
    6.实体:ScheduleJob.class,枚举:JobOperateEnum
    @TableName("schedule_job")
    public class ScheduleJob implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 任务名称
         */
        private String jobName;
    
        /**
         * cron表达式
         */
        private String cronExpression;
    
        /**
         * 服务名称
         */
        private String beanName;
    
        /**
         * 方法名称
         */
        private String methodName;
    
        /**
         * 状态 1.启动 2.暂停
         */
        private int status;
    
        /**
         * 是否删除 0.否 1.是
         */
        @TableField(fill = FieldFill.INSERT)
        @TableLogic
        private Boolean deleteFlag;
    
        /**
         * 创建人id
         */
        @TableField(fill = FieldFill.INSERT)
        private Integer creatorId;
    
        /**
         * 创建人
         */
        @TableField(fill = FieldFill.INSERT)
        private String creatorName;
    
        /**
         * 创建时间
         */
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime createdTime;
    
        /**
         * 更新时间
         */
        @TableField(fill = FieldFill.UPDATE)
        private LocalDateTime updatedTime;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getJobName() {
            return jobName;
        }
    
        public void setJobName(String jobName) {
            this.jobName = jobName;
        }
    
        public String getCronExpression() {
            return cronExpression;
        }
    
        public void setCronExpression(String cronExpression) {
            this.cronExpression = cronExpression;
        }
    
        public String getBeanName() {
            return beanName;
        }
    
        public void setBeanName(String beanName) {
            this.beanName = beanName;
        }
    
        public String getMethodName() {
            return methodName;
        }
    
        public void setMethodName(String methodName) {
            this.methodName = methodName;
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    
        public Boolean getDeleteFlag() {
            return deleteFlag;
        }
    
        public void setDeleteFlag(Boolean deleteFlag) {
            this.deleteFlag = deleteFlag;
        }
    
        public Integer getCreatorId() {
            return creatorId;
        }
    
        public void setCreatorId(Integer creatorId) {
            this.creatorId = creatorId;
        }
    
        public String getCreatorName() {
            return creatorName;
        }
    
        public void setCreatorName(String creatorName) {
            this.creatorName = creatorName;
        }
    
        public LocalDateTime getCreatedTime() {
            return createdTime;
        }
    
        public void setCreatedTime(LocalDateTime createdTime) {
            this.createdTime = createdTime;
        }
    
        public LocalDateTime getUpdatedTime() {
            return updatedTime;
        }
    
        public void setUpdatedTime(LocalDateTime updatedTime) {
            this.updatedTime = updatedTime;
        }
    }
    
    public enum JobOperateEnum {
        START(1, "启动"),
        PAUSE(2, "暂停"),
        DELETE(3, "删除");
    
        private final Integer value;
        private final String desc;
    
        JobOperateEnum(final Integer value, final String desc) {
            this.value = value;
            this.desc = desc;
        }
    
        public Serializable getValue() {
            return this.value;
        }
    
        // Jackson 注解为 JsonValue 返回中文 json 描述
        public String getDesc() {
            return this.desc;
        }
    
        public String getEnumName() {
            return name();
        }
    }
    
    7.任务的调度工厂(主要是实现具体的执行)QuartzFactory.class
    public class QuartzFactory implements Job {
    
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    
            //获取调度数据
            ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
    
            //获取对应的Bean
            Object object = SpringUtil.getBean(scheduleJob.getBeanName());
            try {
                //利用反射执行对应方法
                Method method = object.getClass().getMethod(scheduleJob.getMethodName());
                method.invoke(object);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    8.具体的任务调度以及触发设置:QuartzServiceImpl.class(略过接口)
    @Service
    @Transactional
    public class QuartzServiceImpl implements QuartzService {
    
        /**
         * 调度器
         */
        @Autowired
        private Scheduler scheduler;
    
        @Autowired
        private ScheduleJobService jobService;
    
        @Override
        public void timingTask() {
    
            //查询数据库是否存在需要定时的任务
            List<ScheduleJob> scheduleJobs = jobService.list();
            if (scheduleJobs != null) {
                scheduleJobs.forEach(this::addJob);
            }
        }
    
        @Override
        public void addJob(ScheduleJob job) {
            try {
                //创建触发器
                Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName())
                        .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
                        .startNow()
                        .build();
    
                //创建任务
                JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class)
                        .withIdentity(job.getJobName())
                        .build();
    
                //传入调度的数据,在QuartzFactory中需要使用
                jobDetail.getJobDataMap().put("scheduleJob", job);
    
                //调度作业
                scheduler.scheduleJob(jobDetail, trigger);
    
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        @Override
        public void operateJob(JobOperateEnum jobOperateEnum, ScheduleJob job) throws SchedulerException {
            JobKey jobKey = new JobKey(job.getJobName());
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail == null) {
                //抛异常
            }
            switch (jobOperateEnum) {
                case START:
                    scheduler.resumeJob(jobKey);
                    break;
                case PAUSE:
                    scheduler.pauseJob(jobKey);
                    break;
                case DELETE:
                    scheduler.deleteJob(jobKey);
                    break;
            }
        }
    
        @Override
        public void startAllJob() throws SchedulerException {
            scheduler.start();
        }
    
        @Override
        public void pauseAllJob() throws SchedulerException {
            scheduler.standby();
        }
    }
    
    9.实现CommandLineRunner接口,以达到开机启动执行:JobSchedule.class
    @Component
    public class JobSchedule implements CommandLineRunner {
    
        @Autowired
        private QuartzService taskService;
    
        /**
         * 任务调度开始
         * @param strings
         * @throws Exception
         */
        @Override
        public void run(String... strings) throws Exception {
            System.out.println("任务调度开始==============任务调度开始");
            taskService.timingTask();
            System.out.println("任务调度结束==============任务调度结束");
        }
    }
    

    10.基础的配置完成,以下是几个简单的例子

    执行的Job1:

    @Component("testJob01")
    @Transactional
    public class TestJob01 {
    
        public void execute() {
            System.out.println("-------------------TestJob01任务执行开始-------------------");
            System.out.println(new Date());
            System.out.println("-------------------TestJob01任务执行结束-------------------");
        }
    }
    

    执行的Job2:

    @Component("testJob02")
    @Transactional
    public class TestJob02 {
    
        public void execute() {
            System.out.println("-------------------TestJob02任务执行开始-------------------");
            System.out.println(new Date());
            System.out.println("-------------------TestJob02任务执行结束-------------------");
        }
    }
    

    配置的数据库:


    image.png

    11.业务类实现:ScheduleJobServiceImpl.class(略过接口)

    @Service
    @Transactional
    public class ScheduleJobServiceImpl extends ServiceImpl<ScheduleJobMapper, ScheduleJob> implements ScheduleJobService {
    
        @Autowired
        private QuartzService quartzService;
    
        @Override
        public void add(ScheduleJob job) {
    
            //此处省去数据验证
            this.save(job);
    
            //加入job
            try {
                quartzService.addJob(job);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void start(int id) {
            //此处省去数据验证
            ScheduleJob job = this.getById(id);
            job.setStatus(1);
            this.updateById(job);
    
            //执行job
            try {
                quartzService.operateJob(JobOperateEnum.START, job);
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void pause(int id) {
            //此处省去数据验证
            ScheduleJob job = this.getById(id);
            job.setStatus(2);
            this.updateById(job);
    
            //执行job
            try {
                quartzService.operateJob(JobOperateEnum.PAUSE, job);
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void delete(int id) {
            //此处省去数据验证
            ScheduleJob job = this.getById(id);
            this.removeById(id);
    
            //执行job
            try {
                quartzService.operateJob(JobOperateEnum.DELETE, job);
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void startAllJob() {
            //此处省去数据验证
            ScheduleJob job = new ScheduleJob();
            job.setStatus(1);
            this.update(job, new QueryWrapper<>());
    
            //执行job
            try {
                quartzService.startAllJob();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void pauseAllJob() {
            //此处省去数据验证
            ScheduleJob job = new ScheduleJob();
            job.setStatus(2);
            this.update(job, new QueryWrapper<>());
    
            //执行job
            try {
                quartzService.pauseAllJob();
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    }
    

    12.Controller类:ScheduleJobController.class

    @RestController
    @RequestMapping("/job")
    public class ScheduleJobController {
    
        @Autowired
        private ScheduleJobService jobService;
    
        @GetMapping(value = "/hello")
        public String helloSpringBoot() {
            return "Hello quartz!";
        }
    
        @GetMapping("/add")
        public String add() {
            ScheduleJob job = new ScheduleJob();
            job.setJobName("任务02");
            job.setCronExpression("0/2 * * * * ?");
            job.setBeanName("testJob02");
            job.setMethodName("execute");
            jobService.add(job);
            return "新增定时任务成功";
        }
    
        @GetMapping("/start/{id}")
        public String start(@PathVariable("id") Integer id) {
            jobService.start(id);
            return "启动定时任务成功";
        }
    
        @GetMapping("/pause/{id}")
        public String pause(@PathVariable("id") Integer id) {
            jobService.pause(id);
            return "暂停定时任务成功";
        }
    
        @GetMapping("/delete/{id}")
        public String delete(@PathVariable("id") Integer id) {
            jobService.delete(id);
            return "删除定时任务成功";
        }
    
        @GetMapping("/startAllJob")
        public String startAllJob() {
            jobService.startAllJob();
            return "启动所有定时任务成功";
        }
    
        @GetMapping("/pauseAllJob")
        public String pauseAllJob() {
            jobService.pauseAllJob();
            return "暂停所有定时任务成功";
        }
    }
    

    使用spring自带的@Scheduled注解实现的定时任务

    @Component
    @EnableScheduling
    public class SchedulerTask {
    
        private int count = 0;
    
        @Scheduled(cron = "*/1 * * * * ?")
        private void process() {
            System.out.println("this is scheduler task runing  " + (count++));
            System.out.println("当前时间:" + LocalTime.now());
        }
    }
    

    除了业务层框架mybatis-plus的个别代码没贴出来,关于quartz的全贴出来了,完整源码:

    https://gitee.com/lanjerry/quartz-demo

    相关文章

      网友评论

          本文标题:Springboot 2.1.2 整合quartz 2.3.0

          本文链接:https://www.haomeiwen.com/subject/fazajqtx.html