quartz-2.2.1定制工具类,方便nutz使用js配置quartz

来源:互联网 发布:java技术分享干货 编辑:程序博客网 时间:2024/06/06 02:56

前言:本文主要提供quartz简单配置的解决方案。

      附上quartzWithtool2.2.1.jar和本人增加的org.quartz.tool包里面的源码下载。

      quartzWithtool2.2.1.jar:csdn下载

      org.quartz.tool包:csdn下载

开发背景:在使用nutz框架的时候,需要用到quartz来开启定时任务的时候,不能像spring那样使用xml配置一系列的定时任务。需要自己编写代码去实现定时任务的添加,不利于代码维护。


使用方法:

1.添加quartzWithtool2.2.1.jar

2.nutz的ioc.js里面添加如下配置信息

quartz : {type : "org.quartz.tool.QuartzBean",fields : {list : [{type : "org.quartz.tool.QuartzBean",fields : {name : "clientdie",clazz : "com.chat.quartz.job.ClientDieJob",trigger : "0 */1 * * * ?"//每到整数分钟就执行ClientDieJob}},{type : "org.quartz.tool.QuartzBean",fields : {name : "faqtip",clazz : "com.chat.quartz.job.FaqTipJob",trigger : "0 0 */1 * * ?",//每到整数小时就执行ClientDieJob和FaqTipJobsimpleDelay : "0s"//启动项目之后立即执行1次FaqTipJob,jobDatas:[{type : "org.quartz.tool.JobData",fields : {key : "mykey",value : "myvalue"}},{type : "org.quartz.tool.JobData",fields : {key : "mybool",value : "false"}}]}} ]}}
 3.在项目启动的时候调用
QuartzTool.loadSchedule(Mvcs.getIoc().get(QuartzBean.class, "quartz") );
  :也可以不使用js配置的方式注入 QuartzBean,可以自行在代码中动态生成QuartzBean,然后调用loadSchedule。

关于QuartzBean的配置说明

//-------------------------单个定时任务对应两个触发器(一个simple一个cron规则)-------------------------------------{type : "com.chat.quartz.QuartzBean",fields : {name : "clientdie",clazz : "com.chat.quartz.job.ClientDieJob",trigger : "0 */1 * * * ?",//每到整数分钟就执行ClientDieJobsimpleDelay : "7s", //启动项目之后7秒开始每间隔1秒执行ClientDieJob,一共执行10次simpleRepeat : "10",simpleRepeatDelay : "1s"}}//-------------------------多个定时任务对应两个触发器(一个simple一个cron规则)-------------------------------------{type : "com.chat.quartz.QuartzBean",fields : {name : "faqtip",clazz : "com.chat.quartz.job.ClientDieJob,com.chat.quartz.job.FaqTipJob",trigger : "0 0 */1 * * ?",//每到整数小时就执行ClientDieJob和FaqTipJobsimpleDelay : "0s",//启动项目之后立即每间隔2秒执行ClientDieJob和FaqTipJob,一共执行3次simpleRepeat : "3",simpleRepeatDelay : "2s"}}//-------------------------一个定时任务对应一个simple------------------------------------{type : "com.chat.quartz.QuartzBean",fields : {name : "faqtipsimple5",clazz : "com.chat.quartz.job.FaqTipJob",simpleDelay : "0s",//启动项目之后立即每间隔5秒执行FaqTipJob,不限执行次数simpleRepeat : "-1",simpleRepeatDelay : "5s"}}//-----------------------------------如果需要给定时任务传递数据请配置jobDatas属性-------------------------------------------jobDatas:[{type : "com.chat.quartz.JobData",fields : {key : "mykey",value : "myvalue"}},{type : "com.chat.quartz.JobData",fields : {key : "mybool",value : "false"}}]//设置了jobdata之后,在具体的job里面 像下面那样使用使用System.out.println( arg0.getJobDetail().getJobDataMap().get("mykey") );System.out.println( arg0.getJobDetail().getJobDataMap().getBooleanValue("mybool") );

org.quartz.tool包的源码:


package com.chat.quartz;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.DateBuilder;import org.quartz.DateBuilder.IntervalUnit;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDataMap;import org.quartz.JobDetail;import org.quartz.ScheduleBuilder;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.SimpleScheduleBuilder;import org.quartz.SimpleTrigger;import org.quartz.Trigger;import org.quartz.TriggerBuilder;import org.quartz.impl.StdSchedulerFactory;import org.quartz.spi.MutableTrigger;/** * 定时任务工具类 *  * @author hp *  */public class QuartzTool {/** * quartz的Scheduler工厂类 */private static SchedulerFactory sf = null;/** * 定时器map,主要是停止定时器的时候使用 */private static Map <String, Scheduler> schedMap= new HashMap<String, Scheduler>();    /**     * 定时器配置对象     */private static QuartzBean quartzBean = null;/**     * 启动定时器     * @param key 定时器名称     */    private static void startSchedule(String key){    for (QuartzBean bean : getQuartzBean().getList()) {    if(bean.getName().equals( key )){    startSchedule(bean);    break;    }}    }        /**     * 重新启动定时器     * @param key 定时器名称     */    public void reStartSchedule(String key){    for (QuartzBean bean : getQuartzBean().getList()) {    if(bean.getName().equals( key )){    shutdownSchedule(key);    startSchedule(bean);    break;    }    }    }    /**     * 获取定时器配置对象     * @return     */    public static QuartzBean getQuartzBean() {return quartzBean;}/**     * 启动定时器     * @param bean 定时bean的     */    public static void startSchedule(QuartzBean bean){        try {    //map使用bean的name作为key    String key = bean.getName();    if( schedMap.containsKey(key) ){//如果已经启动了该定时器,先停止再启动    shutdownSchedule(key);    }        Scheduler sched = getSf().getScheduler();        //根据配置生成job集合    Set<JobDetail> jobSet = makeJobSet( bean );    if(jobSet.size() <= 0){    System.out.println("初始化SCheduler失败:" + bean.getName()+"没有配置job的clazz属性。");    return ;    }            //根据配置bean生成trigger集合    Set<Trigger> tSet = makeTriggerSet( bean );    if(tSet.size() <= 0){    System.out.println("初始化SCheduler失败:" + bean.getName()+"没有配置任何trigger。");        return ;    }        //根据job集合和触发器集合生成schedule需要的map参数    Map map = makeSchedMap(jobSet, tSet);        sched.scheduleJobs(map, true);    //sched.scheduleJob( job, tSet , true);    sched.start();        schedMap.put(key, sched);    } catch (SchedulerException e) {    e.printStackTrace();    } catch (ClassNotFoundException e) {    e.printStackTrace();    }    }        /**     * 根据job集合和触发器集合生成schedule需要的map参数     * @param jobSet     * @param tSet     * @return     */    private static Map makeSchedMap(Set<JobDetail> jobSet, Set<Trigger> tSet) {    Map map = new HashMap();    int i = 0;//job循环变量    for (JobDetail job : jobSet) {    Set<Trigger> cloneTriggerSet = new HashSet<Trigger>();    //根据每个任务动态生成对应的jobkey    for (Trigger trigger : tSet) {    MutableTrigger mTrigger = (MutableTrigger) trigger;        if(mTrigger != null){    MutableTrigger cloneTrigger = (MutableTrigger) mTrigger.clone();    cloneTrigger.setJobKey(job.getKey());    //因为triggerkey不能重复,所以这里重新设置trigger的key为原来的值加上jobkey的值    cloneTrigger.setKey(cloneTrigger.getKey().triggerKey(    cloneTrigger.getKey().getName() + cloneTrigger.getJobKey()));    //为了让trigger同时触发的时候有个优先顺序,这里设置一下优先级,job越靠前的 优先级越高    cloneTrigger.setPriority(Trigger.DEFAULT_PRIORITY + 90 - i);        cloneTriggerSet.add(cloneTrigger);    }}        map.put(job, cloneTriggerSet);        i ++;}    return map;}/**     * 根据配置生成job集合     * @param bean     * @return     * @throws ClassNotFoundException      */    private static Set<JobDetail> makeJobSet(QuartzBean bean) throws ClassNotFoundException {    Set<JobDetail> jobSet = new HashSet<JobDetail>();      //clazz没有直接返回    if(StringIsEmpty(bean.getClazz()) ){    return jobSet;    }    //构建jobDataMap     JobDataMap jobDataMap = makeJobDataMap(bean);        String[] clazzArr = bean.getClazz().split(",");    for (int i = 0; i < clazzArr.length; i++) {    String clazz = clazzArr[i];    JobDetail job = JobBuilder.newJob((Class<? extends Job>) Class.forName(clazz ))    .usingJobData(jobDataMap)    .withIdentity(bean.getName() + i ) .build();    jobSet.add(job);}    return jobSet;}    /**     * 根据bean里面的JobDatas生成quartz里面的jobDataMap     * @param bean     * @return     */private static JobDataMap makeJobDataMap(QuartzBean bean) {JobDataMap jobDataMap = new JobDataMap();for (JobData jobData : bean.getJobDatas()) {jobDataMap.put(jobData.getKey(), jobData.getValue());}return jobDataMap;}/**     * 生成调度规则集合,暂时只支持一个cron和一个simple     * @param bean 调度规则配置对象     * @return     */    private static Set<Trigger> makeTriggerSet(QuartzBean bean) {    Set<Trigger> tSet = new HashSet<Trigger>();    CronTrigger cTrigger = makeCTrigger( bean );SimpleTrigger sTrigger = makeSTrigger( bean );if( cTrigger!=null ) tSet.add(cTrigger);if( sTrigger!=null ) tSet.add(sTrigger);return tSet;}    /**     * 生成简单的trigger     * @param bean     * @return     */private static SimpleTrigger makeSTrigger(QuartzBean bean) {    //根据delay生成相对当前时间的一个时间,只支持加时间。    Date beginDate = makeDate( bean.getSimpleDelay() );    if( beginDate == null )    return null;    //简单调度规则的开始时间    TriggerBuilder tBulder = TriggerBuilder.newTrigger().withIdentity( "sTrigger", bean.getName() ).startAt(beginDate );    //生成简单调度规则的重复次数    ScheduleBuilder sBulder = makeSimpleTriggerRepeat(bean);    if(sBulder != null)    tBulder.withSchedule(sBulder);        SimpleTrigger sTrigger = (SimpleTrigger) tBulder.build();    return sTrigger;}/** * 根据规则生成trigger * @param bean 调度任务配置对象 * @return */private static CronTrigger makeCTrigger(QuartzBean bean) {//调度规则String role = bean.getTrigger();if( StringIsEmpty(role) ){return null;}CronScheduleBuilder schedule = CronScheduleBuilder.cronSchedule(role);CronTrigger trigger = TriggerBuilder.newTrigger().withSchedule(schedule).withIdentity( "cTrigger", bean.getName() ).build();return trigger;}/** * 生成简单调度规则的重复次数 * @param bean * @return */private static ScheduleBuilder makeSimpleTriggerRepeat(QuartzBean bean) {ScheduleBuilder sBulder = null;//重复次数Integer count = bean.getSimpleRepeat();//不重复直接返回null,重复次数为0 或者没有重复的间隔时间即为不重复if( count == 0 || StringIsEmpty(bean.getSimpleRepeatDelay() ) ){return null;}//根据delay字符串生成时间对象IntervalObject io = makeIntervalObj(bean.getSimpleRepeatDelay());if(io == null){return null;}if(count == -1)//-1次表示一直循环sBulder = SimpleScheduleBuilder.repeatSecondlyForever(io.getSecond());elsesBulder = SimpleScheduleBuilder.repeatSecondlyForTotalCount(count, io.getSecond() );return sBulder;}/** * 根据delay生成相对当前时间的一个时间,只支持加时间。 * @param delay 相对时间字符串,比如20s(20秒) 3m(3分钟) 60D(60天) * @return */private static Date makeDate(String delay) {if( StringIsEmpty(delay ) ){    return null;    }//根据delay字符串生成时间对象IntervalObject io = makeIntervalObj(delay);if(io == null){return null;}Date date = DateBuilder.futureDate(io.getInterval(), io.getUnit());return date;}/** * 根据delay字符串生成时间对象 * @param delay * @return */private static IntervalObject makeIntervalObj(String delay) {String[] numArr = delay.split("[^\\d]");Integer interval = Integer.valueOf( StringsJoin("", numArr) );if(interval == null || interval < 0){return null;}//不带单位的时候,默认使用毫秒作单位IntervalUnit unit = IntervalUnit.MILLISECOND;if( delay.endsWith("ms") ){unit = IntervalUnit.MILLISECOND;}else if( delay.endsWith("s") ){unit = IntervalUnit.SECOND;}else if( delay.endsWith("m") ){unit = IntervalUnit.MINUTE;}else if( delay.endsWith("D") ){unit = IntervalUnit.DAY;}else if( delay.endsWith("M") ){unit = IntervalUnit.MONTH;}else if( delay.endsWith("Y") ){unit = IntervalUnit.YEAR;}IntervalObject io = new IntervalObject(interval, unit);return io;}/**     * 停止定时器     */    public static void shutdownSchedule(String key) {    if( ! schedMap.containsKey(key)){    return;    }        Scheduler sched = schedMap.remove(key);        if (null != sched) {            try {                sched.shutdown();            } catch (SchedulerException e) {                e.printStackTrace();            }        }    }        /**     * 初始化系统定时器     */    public static void loadSchedule(QuartzBean baseBean){    quartzBean = baseBean;        for (QuartzBean bean : baseBean.getList()) {startSchedule(bean);}    }/** * 获取quartz的Scheduler工厂类 * @return */public static SchedulerFactory getSf() {if(sf == null)sf = new StdSchedulerFactory();return sf;}/**     * 判断字符串是否为null或者空字符串     * @param clazz     * @return     */    private static boolean StringIsEmpty(String str) {if(str == null || str.trim() == ""){return true;}return false;}        /** * 字符串数组连接成一个字符串 * @param split 分割字符串 * @param numArr 字符串数组 * @return */private static String StringsJoin(String split, String[] numArr) {StringBuffer sb = new StringBuffer();for (int i = 0; i < numArr.length; i++) {sb.append(numArr[i] );if(i != numArr.length - 1 )sb.append(split);}return sb.toString();}}
/** * Quartz配置的bean * @author chencong * */public class QuartzBean {/* * 定时任务名称 * 用于停止的时候使用 */private String name;/** * 任务的class<br/> * 多个调度任务的情况下,使用,分割 */private String clazz;/** * 定时任务的数据集合 */private List<JobData> jobDatas = new ArrayList<JobData>();/** * 调度规则 */private String trigger;/** * 启动后多久执行一次,简单调度规则的开始时间<br/> * 格式使用数字加单位,纯数字的单位为ms(毫秒)<br/> * 单位:ms(毫秒) s(秒) m(分) h(小时) D(天) M(月) Y(年)<br/> * 比如20s(20秒) 3m(3分钟) 60D(60天) */private String simpleDelay;/** * 简单调度规则的重复次数 0表示不重复 -1表示一直重复 <br/> * 默认为1 当指定了简单调度规则但是没指定重复次数默认执行1次 */private Integer simpleRepeat = 1;/** * 简单调度规则的重复间隔时间<br/> * 格式使用数字加单位,纯数字的单位为ms(毫秒)<br/>         * 单位:ms(毫秒) s(秒) m(分) h(小时) D(天) M(月) Y(年)<br/> * 比如20s(20秒) 3m(3分钟) 60D(60天)         * 没有指定这个属性不会重复执行简单调度规则 */private String simpleRepeatDelay;/** * Quartz配置集合 用于多 */private List<QuartzBean> list = new ArrayList<QuartzBean>();public String getName() {return name;}public void setName(String name) {this.name = name;}public String getClazz() {return clazz;}public void setClazz(String clazz) {this.clazz = clazz;}public String getTrigger() {return trigger;}public void setTrigger(String trigger) {this.trigger = trigger;}public List<QuartzBean> getList() {return list;}public void setList(List<QuartzBean> list) {this.list = list;}public String getSimpleDelay() {return simpleDelay;}public void setInitDelay(String simpleDelay) {this.simpleDelay = simpleDelay;}public Integer getSimpleRepeat() {return simpleRepeat;}public void setSimpleRepeat(Integer simpleRepeat) {this.simpleRepeat = simpleRepeat;}public String getSimpleRepeatDelay() {return simpleRepeatDelay;}public void setSimpleRepeatDelay(String simpleRepeatDelay) {this.simpleRepeatDelay = simpleRepeatDelay;}public List<JobData> getJobDatas() {return jobDatas;}public void setJobDatas(List<JobData> jobDatas) {this.jobDatas = jobDatas;}}
package com.chat.quartz;/** * 定时任务的数据 * @author lenovo * */public class JobData{private String key;private Object value;public String getKey() {return key;}public void setKey(String key) {this.key = key;}public Object getValue() {return value;}public void setValue(Object value) {this.value = value;}}
package com.chat.quartz;import org.quartz.DateBuilder.IntervalUnit;/** * 时间对象,内部类,包含时间数字和时间单位 * @author lenovo * */public class IntervalObject {/** * 时间的数字 */private Integer interval;/** * 时间的单位 */private IntervalUnit unit;/** * 获取时间的数字 * @return */public Integer getInterval() {return interval;}/** * 设置时间的数字 * @param interval */public void setInterval(Integer interval) {this.interval = interval;}/** * 获取时间的单位 * @return */public IntervalUnit getUnit() {return unit;}/** * 设置时间的单位 * @param unit */public void setUnit(IntervalUnit unit) {this.unit = unit;}/** * 获取时间的秒数 * @return */public Integer getSecond(){if(this.getUnit() == null){return null;}Integer Second = null;switch (getUnit()) {case MILLISECOND:Second = (int) Math.ceil(this.getInterval() / 1000.0 );break;case SECOND:Second = this.getInterval();break;case MINUTE:Second = this.getInterval() * 60;break;case HOUR:Second = this.getInterval() * 60 * 60;break;case DAY:Second = this.getInterval() * 60 * 60 * 24;break;case MONTH://这里有问题 月按照30天一个月来计算Second = this.getInterval() * 60 * 60 * 24 * 30;break;case YEAR://这里有问题 年按照365天来算Second = this.getInterval() * 60 * 60 * 24 * 365;break;default:break;}return Second;}public IntervalObject(Integer interval, IntervalUnit unit) {super();this.interval = interval;this.unit = unit;}public IntervalObject() {super();}}

                                             
1 0