zoukankan      html  css  js  c++  java
  • Quartz定时任务调度

    一、简介
       Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数;例如,在使用 WebSphere 应用服务器时,由 Quartz 调度的作业并不能影响服务器的动态缓存和数据源。
    二、要使用Quartz,需要引入以下包
      1、log4j-1.2.16
      2、quartz-2.1.7
      3、slf4j-api-1.6.1.jar
      4、slf4j-log4j12-1.6.1.ja
    三、了解几个接口
    首先了解三个概念:
    调度器 (Scheduler): 负责调度作业和触发器;
     
    触发器(trigger)      设置作业执行的时间、参数、条件等;(简单触发器和Cron触发器)
     
     作业(Job)             :定时任务内容,被执行的程序;
    下载必要的jar包,直接去官网下载 (http://www.opensymphony.com/quartz/download.action),将quartz-x.x.x.jar 和core 和/或 optional 文件夹中的 jar 文件放在项目的文件夹或项目的类路径中
     
    四、Quartz的几个核心的接口和类
    Job接口:  自己写的“定时程序”实现此接口的void execute(JobExecutionContext arg0)方法,Job还有一类为有状态的StatefulJob接口,如果我们需要在上一个作业执行完后,根据其执行结果再进行下次作业的执行,则需要实现此接口。
    Trigger抽象类:  调度类(Scheduler)在时间到时调用此类,再由trigger类调用指定的定时程序。
    Quertz中提供了两类触发器为:SimpleTrigger,CronTrigger。前者用于实现比较简单的定时功能,例如几点开始,几点结束,隔多长时间执行,共执行多少次等,后者提供了使用表达式来描述定时功能,因此适用于比较复杂的定时描述,例如每个月的最后一个周五,每周的周四等。
     
    JobDetail类:  具体某个定时程序的详细描述,包括Name,Group,JobDataMap等。
    JobExecutionContext类:  定时程序执行的run-time的上下文环境,用于得到当前执行的Job的名字,配置的参数等。
    JobDataMap类:  用于描述一个作业的参数,参数可以为任何基本类型例如String,float等,也可为某个对象的引用.
    JobListener,TriggerListener接口:  用于监听触发器状态和作业扫行状态,在特写状态执行相应操作。
    JobStore类:  在哪里执行定进程序,可选的有在内存中,在数据库中。
     
    四、下面来配置Quartz框架在Spring中的引用
        1.新建一个定时任务管理类,命名为QuartzJobManager
    package com.shpte.paramfrm.quartz;
    
    import java.util.Map;
    
    import org.quartz.CronTrigger;
    import org.quartz.JobDetail;
    import org.quartz.Scheduler;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.stereotype.Controller;
    
    /**
     * @Description: 定时任务管理类
     * 
     * @ClassName: QuartzJobsManager
     */
    
    @Controller
    public class QuartzJobsManager
    {
    
        @Autowired
        private SchedulerFactoryBean schedulerFactory;
        
        private  String JOB_GROUP_NAME = "AFC_JOBGROUP_NAME";
        private  String TRIGGER_GROUP_NAME = "AFC_TRIGGERGROUP_NAME";
    
        /**
         * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
         * 
         * @param jobName
         *            任务名
         * @param cls
         *            任务
         * @param time
         *            时间设置,参考quartz说明文档
         * 
         */
        
        @SuppressWarnings("unchecked")
        public void addJob(String jobName, Class cls, String time)
        {
            try
            {
                
                Scheduler sched = schedulerFactory.getScheduler();
                JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类
                // 触发器
                CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
                trigger.setCronExpression(time);// 触发器时间设定
                sched.scheduleJob(jobDetail, trigger);
                
                // 启动
                if (!sched.isShutdown())
                {
                    sched.start();
                }
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
        
        @SuppressWarnings("unchecked")
        public  void addJob(String jobName, Class cls, String time, Map<String, Object> jobDataMap)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类
                jobDetail.getJobDataMap().putAll(jobDataMap);
                // 触发器
                CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
                trigger.setCronExpression(time);// 触发器时间设定
                sched.scheduleJob(jobDetail, trigger);
                // 启动
                if (!sched.isShutdown())
                {
                    sched.start();
                }
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description: 添加一个定时任务
         * 
         * @param jobName
         *            任务名
         * @param jobGroupName
         *            任务组名
         * @param triggerName
         *            触发器名
         * @param triggerGroupName
         *            触发器组名
         * @param jobClass
         *            任务
         * @param time
         *            时间设置,参考quartz说明文档
         */
        @SuppressWarnings("unchecked")
        public  void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String time)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass);// 任务名,任务组,任务执行类
                // 触发器
                CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
                trigger.setCronExpression(time);// 触发器时间设定
                sched.scheduleJob(jobDetail, trigger);
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
         * 
         * @param jobName
         * @param time
         */
        @SuppressWarnings("unchecked")
        public  void modifyJobTime(String jobName, String time)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
                if (trigger == null)
                {
                    return;
                }
                String oldTime = trigger.getCronExpression();
                if (!oldTime.equalsIgnoreCase(time))
                {
                    JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);
                    Class objJobClass = jobDetail.getJobClass();
                    removeJob(jobName);
                    addJob(jobName, objJobClass, time);
                }
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description: 修改一个任务的触发时间
         * 
         * @param triggerName
         * @param triggerGroupName
         * @param time
         */
        public  void modifyJobTime(String triggerName, String triggerGroupName, String time)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);
                if (trigger == null)
                {
                    return;
                }
                String oldTime = trigger.getCronExpression();
                if (!oldTime.equalsIgnoreCase(time))
                {
                    CronTrigger ct = (CronTrigger) trigger;
                    // 修改时间
                    ct.setCronExpression(time);
                    // 重启触发器
                    sched.resumeTrigger(triggerName, triggerGroupName);
                }
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
         * 
         * @param jobName
         */
        public  void removeJob(String jobName)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
                sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
                sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description: 移除一个任务
         * 
         * @param jobName
         * @param jobGroupName
         * @param triggerName
         * @param triggerGroupName
         */
        public  void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName)
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器
                sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器
                sched.deleteJob(jobName, jobGroupName);// 删除任务
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description:启动所有定时任务
         */
        public  void startJobs()
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                sched.start();
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * @Description:关闭所有定时任务
         * 
         */
        public  void shutdownJobs()
        {
            try
            {
                Scheduler sched = schedulerFactory.getScheduler();
                if (!sched.isShutdown())
                {
                    sched.shutdown();
                }
            } catch (Exception e)
            {
                throw new RuntimeException(e);
            }
        }
    }
    2、新建一个QuartzTestJob类来实现Job接口
    package com.shpte.paramfrm.quartz.jobs;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    
    public class QuartzTestJob implements Job
    {
    
        @Override
        public void execute(JobExecutionContext jobCtx) throws JobExecutionException
        {
            // jobCtx.getJobDetail().getJobDataMap().get(key)
            
            System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "★★★★★★★★★★★");
            //QuartzJobsManager.removeJob("动态任务调度");
        }
    
    }
    3、开始将Quartz与Spring整合
      
     (1)、新建一个JobFactory继承AdaptableJobFactory类
    package com.shpte.paramfrm.quartz.jobs;
    
    import org.quartz.spi.TriggerFiredBundle;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
    import org.springframework.scheduling.quartz.AdaptableJobFactory;
    
    
    public class JobFactory extends AdaptableJobFactory {  
        
        @Autowired  
        private AutowireCapableBeanFactory capableBeanFactory;  
      
        @Override  
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {  
            //调用父类的方法  
            Object jobInstance = super.createJobInstance(bundle);  
            //进行注入  
            capableBeanFactory.autowireBean(jobInstance);  
            return jobInstance;  
        }  
          
    }
    (2)、新建一个applicationContext-quartz.xml文件,注入Quartz到Spring
       
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
            default-lazy-init="true">
    
        <description>定时任务</description>
        
        <bean id="schedulerFactoryBean" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" scope="singleton">
            <property name="jobFactory">
                <bean class="com.shpte.paramfrm.quartz.jobs.JobFactory"></bean>  
            </property>  
        </bean>
            
    </beans>
    4、新建一个Job任务
    package com.shpte.paramfrm.quartz.jobs;
    
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.quartz.StatefulJob;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.shpte.common.param.manager.DraftParamManager;
    import com.shpte.dubbo.provider.IDraftParamService;
    
    
    public class QuartzEffectDraftParamLCC implements StatefulJob
    {
        private static final Logger log = LoggerFactory.getLogger(QuartzEffectDraftParamLCC.class);
        
        public static final String DEFAULT_JOB_NAME = "HBparam";    //这个 DEFAULT_JOB_NAME只给Quartz用
        //0 0/30 * * * ?  每隔一分钟  执行一次   0 */1 * * * ? 
        public static final String DEFAULT_JOB_TIME = " 0 5 9 22 2 ? 2017 "; //这个 DEFAULT_JOB_TIME只给Quartz用
        
        public static final Integer REPLY_TIME_OUT = 300000;
    
        @Autowired
        public DraftParamManager draftParamManager;
        
        @Autowired
        public IDraftParamService draftParamService;
    
        @Override
        public void execute(JobExecutionContext jobCtx) throws JobExecutionException
        {
            log.info(" ★★★★★★★★★★★ 开始执行任务 : " + jobCtx.getJobDetail().getName());
            
            if (!draftParamManager.effectiveDraftParam("DraftParamLcc",TinyTools.nowStr())))
            {
                log.info("-----草稿参数生效失败------");
            } else
            {
                log.info("-----草稿参数生效成功------");
            }
            return;
        }
    
    }
    5、添加一个Init()方法,调用任务类并且运行
      这里调用了有三个任务,上面我只写了一个任务。
    @PostConstruct
        private void init()
        {
            log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectFutureParamCCHS.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectFutureParamCCHS.DEFAULT_JOB_TIME);
            quartzJobsManager.addJob(QuartzEffectFutureParamCCHS.DEFAULT_JOB_NAME, QuartzEffectFutureParamCCHS.class, QuartzEffectFutureParamCCHS.DEFAULT_JOB_TIME);
            
            log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectFutureParamLCC.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectFutureParamLCC.DEFAULT_JOB_TIME);
            quartzJobsManager.addJob(QuartzEffectFutureParamLCC.DEFAULT_JOB_NAME, QuartzEffectFutureParamLCC.class, QuartzEffectFutureParamLCC.DEFAULT_JOB_TIME);
            
            log.info(" ★★★★★★★★★★★ 启动默认任务 : " + QuartzEffectDraftParamLCC.DEFAULT_JOB_NAME +" 触发时间:" + QuartzEffectDraftParamLCC.DEFAULT_JOB_TIME);
            quartzJobsManager.addJob(QuartzEffectDraftParamLCC.DEFAULT_JOB_NAME, QuartzEffectDraftParamLCC.class, QuartzEffectDraftParamLCC.DEFAULT_JOB_TIME



    总结:以上就是一个完整的Quartz框架搭建、在Spring中整合、以及定制一个任务来在定时定点触发执行的完成步骤及完整代码。
    );
            loadParam();
        }
    6、看控制台日志
      
     
     
    最怕你一生碌碌无为 还安慰自己平凡可贵
  • 相关阅读:
    javax.xml.ws.WebServiceException: Provider com.sun.xml.ws.spi.ProviderImpl not found
    注意资源利用 不然导致资源消耗会很严重
    E212: 不能以写入模式打开 linux
    安装db2 提示不是有效的win32应用程序?
    对苹果“五仁”编程语言Swift的简单分析
    Spoj 1557 Can you answer these queries II 线段树 随意区间最大子段和 不反复数字
    Oracle 学习笔记 14 -- 集合操作和高级子查询
    PHP的curl库代码使用
    AWS OpsWorks新增Amazon RDS支持
    最短编辑距离算法
  • 原文地址:https://www.cnblogs.com/Thinkingcao/p/7249791.html
Copyright © 2011-2022 走看看