zoukankan      html  css  js  c++  java
  • SpringBoot整合quartz实现动态启动,停止定时任务功能

    引入maven

      <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-quartz</artifactId>
            </dependency>

    TaskJob.java   任务执行类

    package com.test.cms.task;
    
    import com.test.cms.service.TaskService;
    import org.quartz.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.Date;
    
    /**
     * @PersistJobDataAfterExecution 和 @DisallowConcurrentExecution
     * 表示不让某个定时任务并发执行保证上一个任务执行完后,再去执行下一个任务
     */
    @PersistJobDataAfterExecution
    @DisallowConcurrentExecution
    @Component
    public class TaskJob implements Job {
    
        /**
         * 可以直接注入service层。这里只是演示,没有这个类
         */
        @Autowired
        private TaskService taskService;
    
    
        @Override
        public void execute(JobExecutionContext context)  {
            JobDataMap jobDataMap=context.getJobDetail().getJobDataMap();
            System.out.println("11"+new Date()+"    "+jobDataMap.getString("value")+"  "+context.getJobDetail().getKey());
        }
    
    
    }

    控制器

    TaskController.java

    package com.test.cms.controller;
    
    import com.test.cms.task.TaskJob;
    import org.quartz.JobDataMap;
    import org.quartz.JobKey;
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
    import org.springframework.scheduling.quartz.JobDetailFactoryBean;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.*;
    
    @RestController
    public class TaskController {
    
        /**
         * 启动任务 需要自己完善逻辑,这里我用uuid作为taskCode 保证唯一
         * 启动之前要通过数据库查询是否任务已经启动,如果启动了就不能启动了
         * 启动成功了 要把数据库的任务状态改为启动中
         */
        @RequestMapping(value = "/task/start")
        public void start() {
            String uuid = UUID.randomUUID().toString();
            System.out.println(uuid);
            startTask(uuid);
    
        }
    
        /**
         * 停止任务 需要自己完善逻辑
         * @param taskCode 传入启动任务时设置的taskCode参数
         */
        @RequestMapping(value = "/task/stop")
        public void stop(String taskCode) {
            endTask(taskCode);
        }
    
        /**
         * 开始任务调度
         *
         * @param taskCode 任务名称 需要唯一标识,停止任务时需要用到
         */
        private void startTask(String taskCode){
            //任务开始的corn表达式
            String cronExpress = "*/5 * * * * ?";
            if (cronExpress.indexOf("null") == -1) {
                try {
                    JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
                    jobDetailFactoryBean.setName(taskCode);
                    jobDetailFactoryBean.setGroup(Scheduler.DEFAULT_GROUP);
                    //TaskJob.class 是任务所要执行操作的类
                    jobDetailFactoryBean.setJobClass(TaskJob.class);
                    //任务需要的参数可以通过map方法传递,
                    Map map = new HashMap();
                    map.put("value", "我在传递参数");
                    jobDetailFactoryBean.setJobDataMap(getJobDataMap(map));
                    jobDetailFactoryBean.afterPropertiesSet();
                    CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
                    cronTriggerFactoryBean.setBeanName(taskCode);
                    cronTriggerFactoryBean.setCronExpression(cronExpress);
                    cronTriggerFactoryBean.setGroup(Scheduler.DEFAULT_GROUP);
                    cronTriggerFactoryBean.setName("cron_" + taskCode);
                    cronTriggerFactoryBean.afterPropertiesSet();
                    scheduler.scheduleJob(jobDetailFactoryBean.getObject(), cronTriggerFactoryBean.getObject());
                    System.out.println(taskCode+"任务启动成功");
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println(taskCode+"任务启动失败");
                }
            }
        }
    
    
        /**
         * 结束任务调度
         *
         * @param taskCode
         */
        private void endTask(String taskCode)  {
            try {
                scheduler.deleteJob(JobKey.jobKey(taskCode, Scheduler.DEFAULT_GROUP));
                System.out.println(taskCode+"任务停止成功");
            } catch (SchedulerException e) {
                e.printStackTrace();
                System.out.println(taskCode+"任务停止失败");
            }
        }
    
    
        /**
         * 将HashMap转为JobDataMap
         * @param params
         * @return
         */
        private JobDataMap getJobDataMap(Map<String, String> params) {
            JobDataMap jdm = new JobDataMap();
            Set<String> keySet = params.keySet();
            Iterator<String> it = keySet.iterator();
            while (it.hasNext()) {
                String key = it.next();
                jdm.put(key, params.get(key));
            }
            return jdm;
        }
    
    
    
        @Autowired
        private Scheduler scheduler;
    }

    启动类要加上注解@EnableScheduling

    package com.test.cms;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @SpringBootApplication
    @EnableScheduling   //要加上开启定时任务的注解
    public class CmsApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(CmsApplication.class, args);
        }
    
    }
  • 相关阅读:
    计算机网络 基础 1
    JAVA 基础之 多线程
    HashMap 多线程处理之 FailFast机制:
    Struts2
    JAVA 由浅及深之 Servlet
    Servlet 会话技术 , Session 及 Cookie 详解
    JAVA 设计模式 : 单例模式
    JAVA 基础之 序列化 Serializable
    代理模式 及 实现AOP 拦截机制
    web.xml 文件详解 及 listener、 filter、servlet 加载顺序
  • 原文地址:https://www.cnblogs.com/pxblog/p/13396085.html
Copyright © 2011-2022 走看看