A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

Quartz 实现动态管理任务
1.Quartz实现动态管理任务


1.1.需求目标
基于Quartz原生API,进行定时任务的动态管理,实现任务的添加、删除、暂停、继续以及任务调度时间的修改。

1.2.纯Java代码实现
1.新建Maven项目,并引入依赖,pom.xml的内容如下:
<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>
        <groupId>cn.itcast.quartz</groupId>
        <artifactId>quartzmanager</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <dependencies>
                <!-- quartz核心 -->
                <dependency>
                        <groupId>org.quartz-scheduler</groupId>
                        <artifactId>quartz</artifactId>
                        <version>2.2.3</version>
                </dependency>
                <!-- slf4j log4j -->
                <dependency>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                        <version>1.7.7</version>
                </dependency>
                <!-- junit测试 -->
                <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>4.12</version>
                </dependency>
        </dependencies>
</project>


2.创建工作对象


public class QuartzManager {
        
        //用于创建Scheduler的工厂对象。默认情况下是加载当前工作目录下的”quartz.properties”属性文件。如果加载失败,会去加载org/quartz包下的”quartz.properties”属性文件。
        private static SchedulerFactory schedulerFactory=new StdSchedulerFactory();
        
        /**
         * 启动作业调度(所有定时任务)
         */
        public static void startScheduler() {
                try {
                        //获取调度程序对象,单例
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        //判断是否已经启动了
                        if(!scheduler.isStarted()) {
                                //如果没有启动,则启动
                                scheduler.start();
                        }
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
        }
        
        /**
         * 关闭作业调度(所有定时任务)
         */
        public static void shutdownScheduler() {
                try {
                        //获取调度程序对象,单例
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        //判断是否已经关闭了
                        if(!scheduler.isShutdown()) {
                                //如果没有关闭,则关闭
                                scheduler.shutdown();
                        }
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
               
        }
        

        /**
         * 添加一个定时任务
         * @param jobName 任务名字
         * @param jobGroupName 任务组名
         * @param triggerName 触发器名
         * @param triggerGroupName 触发器组名
         * @param jobClass 任务工作(具体执行)对象的类
         * @param cron 计划任务表达式
         */
        public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass,String cron) {
                //获取调度程序对象,单例
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        //1. 创建任务对象
                        JobDetail jobDetail=
                                        //指定任务工作(具体执行)类
                                        JobBuilder.newJob(jobClass)
                                        //2)使用指定的任务名字和任务组名字来构成JobKey,作为任务的唯一标识。
                                        .withIdentity(jobName,jobGroupName)
                                        .build();
                        
                        //2. 创建触发器对象
                        //触发器任务计划执行表的执行”机制”。多个触发器可以指向同一个工作,但一个触发器只能指向一个工作
                        Trigger trigger=TriggerBuilder.newTrigger()
                                        //使用指定的触发器名字和触发器组名字来构成TriggerKey,作为触发器的唯一标识。
                                        .withIdentity(triggerName, triggerGroupName)
                                        .withSchedule(
                                                        CronScheduleBuilder.cronSchedule(cron)
                                                        )
                                        .build();
                        //3. 作业调度容器设置任务对象和触发器对象
                        scheduler.scheduleJob(jobDetail, trigger);
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
               
        }
        
        /**
         * 通过Cron表达式来修改一个定时任务的触发时间。方式一:直接调用rescheduleJob方法
         * @param triggerName 触发器名
         * @param triggerGroupName 触发器组名
         * @param cron 计划任务表达式
         */
        public static void modifyJobTimeByCron(String triggerName, String triggerGroupName, String cron) {
                //获取调度程序对象,单例
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                        //1. 判断某触发器是否存在
                        TriggerKey triggerKey=TriggerKey.triggerKey(triggerName, triggerGroupName);
                        CronTrigger oldTrigger = (CronTrigger)scheduler.getTrigger(triggerKey);
                        if(oldTrigger==null) {
                                //如果触发器不存在,则返回
                                return;
                        }
                        
                        //2.
                        //获取之前触发器的计划任务表达式
                        String oldCronExpression = oldTrigger.getCronExpression();
                        //判断新旧表达式是否一样
                        if(!oldCronExpression.equalsIgnoreCase(cron)) {
                                //-----方式一:直接调用rescheduleJob方法
                                //如果不一样,则创建一个新的触发器对象
                                Trigger newTrigger=TriggerBuilder.newTrigger()
                                                //使用指定的触发器名字和触发器组名字来构成TriggerKey,作为触发器的唯一标识。
                                                .withIdentity(triggerName, triggerGroupName)
                                                .withSchedule(
                                                                CronScheduleBuilder.cronSchedule(cron)
                                                                )
                                                .build();
                                //该方法先根据triggerKey删除旧的任务,再添加保存新的任务,要求必须是job一样。
                                Date firstFireTimeOfNewTrigger  = scheduler.rescheduleJob(triggerKey, newTrigger);
                                if(firstFireTimeOfNewTrigger==null) {
                                        System.out.println("修改失败!");
                                }
                        }
                        
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
               
        }
        
        /**
         * 通过Cron表达式来修改一个定时任务的触发时间:方式二:先手动删除旧的任务,再手动创建新的任务
         * @param jobName 任务名字
         * @param jobGroupName 任务组名
         * @param triggerName 触发器名
         * @param triggerGroupName 触发器组名
         * @param cron 计划任务表达式
         */
        public static void modifyJobTimeByCron2 (String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) {
                //获取调度程序对象,单例
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                        //1. 判断某触发器是否存在
                        TriggerKey triggerKey=TriggerKey.triggerKey(triggerName, triggerGroupName);
                        CronTrigger oldTrigger = (CronTrigger)scheduler.getTrigger(triggerKey);
                        if(oldTrigger==null) {
                                //如果触发器不存在,则返回
                                return;
                        }
                        
                        //2.
                        //获取之前触发器的计划任务表达式
                        String oldCronExpression = oldTrigger.getCronExpression();
                        //判断新旧表达式是否一样
                        if(!oldCronExpression.equalsIgnoreCase(cron)) {
                                //-----方式二:先手动删除旧的任务,再手动创建新的任务
                                JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
                                JobDetail oldJobDetail = scheduler.getJobDetail(jobKey);
                                Class<? extends Job> jobClass = oldJobDetail.getJobClass();
                                removeJob(jobName, jobGroupName, triggerName, triggerGroupName);  
                                addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
                                
                        }
                        
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
               
        }
        
        /**
         * 删除(移除)一个任务
         * @param jobName
         * @param jobGroupName
         * @param triggerName
         * @param triggerGroupName
         */
        public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
                //获取调度程序对象,单例
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                         TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
                         scheduler.pauseTrigger(triggerKey);// 停止触发器  
                         scheduler.unscheduleJob(triggerKey);// 移除触发器  
                         scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务  
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
               
        }
        
        /**
         * 暂停某任务的触发器
         * @param triggerName
         * @param triggerGroupName
         */
        public static void pauseTrigger(String triggerName, String triggerGroupName) {
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                         TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
                         scheduler.pauseTrigger(triggerKey);// 停止触发器  
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
        }
        /**
         * 恢复某任务的触发器
         * @param triggerName
         * @param triggerGroupName
         */
        public static void resumeTrigger(String triggerName, String triggerGroupName) {
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                        TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
                        scheduler.resumeTrigger(triggerKey);
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
        }
        /**
         * 暂停某任务的执行(底层仍然是暂停触发器)
         * @param jobName
         * @param jobGroupName
         */
        public static void pauseJob(String jobName, String jobGroupName) {
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                        JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
                        scheduler.pauseJob(jobKey);
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
        }
        /**
         * 恢复某任务的执行(底层仍然是恢复触发器)
         * @param jobName
         * @param jobGroupName
         */
        public static void resumeJob(String jobName, String jobGroupName) {
                try {
                        Scheduler scheduler = schedulerFactory.getScheduler();
                        
                        JobKey jobKey=JobKey.jobKey(jobName, jobGroupName);
                        scheduler.resumeJob(jobKey);
                        
                } catch (SchedulerException e) {
                        e.printStackTrace();
                }
        }
        
}

3.junit测试


public class QuartzTest {
        public static String JOB_NAME = "HelloJob";
        public static String TRIGGER_NAME = "HelloTrigger";
        public static String JOB_GROUP_NAME = "HELLO_JOB_GROUP";
        public static String TRIGGER_GROUP_NAME = "HELLO_JOB_GROUP";
        
        @Test
        public void test() throws Exception {
                 System.out.println("【系统启动】开始...");   
                 QuartzManager.startScheduler();
                 System.out.println("【系统启动】成功...");   
                 Thread.sleep(5000);   
                 System.out.println("开始(每1秒输出一次)...");   
         QuartzManager.addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME, HelloJob.class, "0/1 * * * * ?");   
         Thread.sleep(5000);
         System.out.println("执行了5秒后,定时器暂停执行3秒...");
         QuartzManager.pauseTrigger(TRIGGER_NAME, TRIGGER_GROUP_NAME);
         Thread.sleep(3000);
         System.out.println("定时器恢复执行...");  
         QuartzManager.resumeTrigger(TRIGGER_NAME, TRIGGER_GROUP_NAME);
         Thread.sleep(5000);
         System.out.println("【修改时间】开始(每5秒输出一次)...");   
         QuartzManager.modifyJobTimeByCron(TRIGGER_NAME, TRIGGER_GROUP_NAME, "0/5 * * * * ?");  

         Thread.sleep(6000);   
         System.out.println("【移除定时】开始...");   
         QuartzManager.removeJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME);   
         System.out.println("【移除定时】成功");
         Thread.sleep(5000);   
         QuartzManager.shutdownScheduler();
         System.out.println("【系统关闭】...");   
               
        }
}

1 个回复

倒序浏览
我来占层楼啊   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马