Quartz定时任务封装

  通常的系统都会有一些定时任务,那么咱们将这个定时任务封装起来,只要系统须要添加定时任务时,只需调用此方法传入所须要的值便可完成定时任务。  本身自学整理的一些随笔java

1.首先对周期粒度进行封装数组

 

public enum GranularityPeriod{
UNSPECIFIED(0), ONE_MIN(1), TWO_MINS(2), THREE_MINS(3), FOUR_MINS(4), FIVE_MINS(5), SIX_MINS(6), TEN_MINS(10), TWELVE_MINS(
                12), FIFTEEN_MINS(15), TWENTY_MINS(20), THIRTY_MINS(30), ONE_HOUR(60), TWO_HOURS(120), THREE_HOURS(180), FOUR_HOURS(
                240), SIX_HOURS(360), EIGHT_HOURS(480), TWELVE_HOURS(720), TWENTY_FOUR_HOURS(1440);
 private final int value;

        GranularityPeriod(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static GranularityPeriod getGranularityPeriod(int value) {

            switch (value) {
                case 0:
                    return UNSPECIFIED;
                case 1:
                    return ONE_MIN;
                case 2:
                    return TWO_MINS;
                case 3:
                    return THREE_MINS;
                case 4:
                    return FOUR_MINS;
                case 5:
                    return FIVE_MINS;
                case 6:
                    return SIX_MINS;
                case 10:
                    return TEN_MINS;
                case 12:
                    return TWELVE_MINS;
                case 15:
                    return FIFTEEN_MINS;
                case 20:
                    return TWENTY_MINS;
                case 30:
                    return THIRTY_MINS;
                case 60:
                    return ONE_HOUR;
                case 120:
                    return TWO_HOURS;
                case 180:
                    return THREE_HOURS;
                case 240:
                    return FOUR_HOURS;
                case 360:
                    return SIX_HOURS;
                case 480:
                    return EIGHT_HOURS;
                case 720:
                    return TWELVE_HOURS;
                case 1440:
                    return TWENTY_FOUR_HOURS;
            }
            throw new IllegalArgumentException("NOT GranularityPeriod matched the argument!");
        }

}

2.对同步方式进行封装app

public enum DateCycle {
     BY_DAY, BY_WEEK, BY_MONTH;
}
public class DayOfWeek {
    public static String getDay(int i) {

        switch (i) {
            case 0:
                return "Sun";
            case 1:
                return "Mon";
            case 2:
                return "Tue";
            case 3:
                return "Wed";
            case 4:
                return "Thu";
            case 5:
                return "Fri";
            case 6:
                return "Sat";
        }
        throw new IllegalArgumentException("NOT day matched the argument!");
    }
}

3.设置须要定时同步的周期对象ide

(1)同步任务的任务名 跟 任务组名进行封装测试

public class JobInfo {
    private String jobName;
    private String jobGroupName;
    
    public JobInfo(String jobName,String jobGroupName){
        this.jobName = jobName;
        this.jobGroupName = jobGroupName;
    }
    public String getJobName() {
        return jobName;
    }
    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
    public String getJobGroupName() {
        return jobGroupName;
    }
    public void setJobGroupName(String jobGroupName) {
        this.jobGroupName = jobGroupName;
    }
}

(2)定时任务的对象设定,并指定任务名 任务组名ui

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class TimingSync implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final Integer SWTICH_OFF =0;
    public static final Integer BY_DAY =1;
    public static final Integer BY_WEEK =2;
    public static final Integer BY_MONTH =3;
    public static final Integer TYPE_IOPS =0;
    //public static final String IOPS_JOB_NAME ="my_sync";
    //public static final String IOPS_JOB_GROUPNAME ="my_group";
    /**
     * 0--- 定时同步开关关闭
     * 1--- 按天定时
     * 2--- 按周定时
     * 3--- 按月定时
     */
    private Integer status;
    private String day;//按月定时时填写该字段从1开始,第0位表明第一天,如1110101 表明某月的1号,2号,3号,5号,7号    
    private String week;//按周定时时填写该字段从周日开始一共7位0000000,如0100001 表明周一和周六
    private Integer businessType;// 定时任务的业务类型,0表明my_sync,能够扩展其余业务
    private String synctime = "00:00:00";
    
    public final static Map<Integer,EbsJobInfo> JOB_TYPE_NAME_MAP = new HashMap<Integer,JobInfo>();  
    static {  
        JOB_TYPE_NAME_MAP.put(TYPE_MY, new EbsJobInfo("my_sync", "my_group"));   
    }  

    
    public String getWeek() {
        return week;
    }

    public void setWeek(String week) {
        this.week = week;
    }
    
    public String getDay() {
        return day;
    }

    public void setDay(String day) {
        this.day = day;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }


    public String getSynctime() {
        return synctime;
    }

    public void setSynctime(String synctime) {
        this.synctime = synctime;
    }

    @Override
    public String toString() {
        return "TimingSync [businessType="+businessType+", status=" + status + ", week=" + week + ", day=" + day + ", synctime=" + synctime + "]";
    }

    public Integer getBusinessType() {
        return businessType;
    }

    public void setBusinessType(Integer businessType) {
        this.businessType = businessType;
    }

}

4.封装调度机信息,用于存储所须要的同步周期方式this

public class ScheduleInfo implements Serializable, Cloneable {
    
    private static final long serialVersionUID = 3258130271374160953L;
     private String quartzName;

        private String quartzGroup;
        private String executorId;
        private Date startTime;
        private Date endTime;
        private Date tiggerTime;
        private String weekDays, monthDays;
        private DateCycle dateCycle = DateCycle.BY_DAY;

        public String getWeekDays() {
            return weekDays;
        }

        public void setWeekDays(String weekDays) {
            this.weekDays = weekDays;
        }

        public String getMonthDays() {
            return monthDays;
        }

        public void setMonthDays(String monthDays) {
            this.monthDays = monthDays;
        }

        public Date getEndTime() {
            return endTime;
        }

        public void setEndTime(Date endTime) {
            this.endTime = endTime;
        }

        public Date getStartTime() {
            return startTime;
        }

        public void setStartTime(Date startTime) {
            this.startTime = startTime;
        }


        public String getExecutorId() {

            return executorId;
        }

        public void setExecutorId(String executorId) {

            this.executorId = executorId;
        }

        public String getQuartzGroup() {

            return quartzGroup;
        }

        public void setQuartzGroup(String quartzGroup) {

            this.quartzGroup = quartzGroup;
        }

        public String getQuartzName() {

            return quartzName;
        }

        public void setQuartzName(String quartzName) {

            this.quartzName = quartzName;
        }
        private GranularityPeriod granularityPeriod = GranularityPeriod.ONE_MIN;

        public static ScheduleInfo newInstance(Date startTime, Date stopTime) {

            ScheduleInfo schedule = new ScheduleInfo();

            schedule.startTime = startTime;
            schedule.endTime = stopTime;

            return schedule;
        }


        public Date getTiggerTime() {
            return tiggerTime;
        }

        public void setTiggerTime(Date tiggerTime) {
            this.tiggerTime = tiggerTime;
        }

        public Object clone() throws CloneNotSupportedException {
            ScheduleInfo clone = (ScheduleInfo) super.clone();
            if(null == this.startTime){
                clone.startTime = null;
            }
            else{
                clone.startTime = (Date) this.startTime.clone();
            }
            if(null == this.endTime){
                this.endTime = null;
            }
            else{
                clone.endTime = (Date) this.endTime.clone();
            }
            return clone;
        }

        public GranularityPeriod getGranularityPeriod() {
            return granularityPeriod;
        }

        public void setGranularityPeriod(GranularityPeriod granularityPeriod) {
            this.granularityPeriod = granularityPeriod;
        }

        public DateCycle getDateCycle() {
            return dateCycle;
        }

        public void setDateCycle(DateCycle dateCycle) {
            this.dateCycle = dateCycle;
        }
}

5.封装方法生成设定的所指望的同步规则spa

public class CronTriggerUtil {
//     所须要的符号
        /**
         * Comment for <code>SPACE</code>
         */
        public final static String SPACE = " ";

        /**
         * Comment for <code>ZERO</code>
         */
        public final static String ZERO = "0";

        /**
         * Comment for <code>SUB</code>
         */
        public final static String SUB = "-";

        /**
         * Comment for <code>DIV</code>
         */
        public final static String DIV = "/";

        /**
         * Comment for <code>ASTERISK</code>
         */
        public final static String ASTERISK = "*";

        /**
         * Comment for <code>INTERROGATION</code>
         */
        public final static String INTERROGATION = "?";

        /**
         * Comment for <code>COMMA</code>
         */
        public final static String COMMA = ",";


        /**
         * 根据传入的自定义的定时方式生成trigger所认识的定时任务规则
         * 
         */
        public String toCronExpr(ScheduleInfo schedule) {
            String expr = toTimeCronExpr(schedule) + toDateCronExpr(schedule);
            return expr;
        }

        /**
         * 得到时间表达式,分为3中状况处理,分别是:没有时间段,有一个时间段,有多个时间段,
         */
        private String toTimeCronExpr(ScheduleInfo schedule) {

            StringBuilder result = new StringBuilder();


            // 用开始时间做为启动时间
            Date date = schedule.getStartTime();
            Date currentDate = new Date(System.currentTimeMillis());
            if(date == null){
                date = currentDate;
            }
            int setSecond = getStartSeconds(date);
            if(setSecond < 59){//59+1的话会致使开始时间大于触发时间,定时任务会延迟一个周期触发,因此这里去掉59s时的加1操做
                setSecond = setSecond+1;
            }
            if(setSecond == 60){
                setSecond = 0;
            }

            result.append(setSecond).append(SPACE);

            // 特殊处理,在周期为天,判断tiggerTime。24小时
            if(schedule.getGranularityPeriod().value() == 1440){
                // date = new Date(date.getTime() + 1000 * 60 * 60);
                result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE);

            }
            // 特殊处理,在周期为天,判断tiggerTime。12小时
            else if(schedule.getGranularityPeriod().value() == 720){
                // date = new Date(date.getTime() + 1000 * 60 * 60);
                result.append(getStartMinute(date)).append(SPACE);
                if(schedule.getEndTime() != null && schedule.getEndTime().getTime() - date.getTime() < 43200000){
                    result.append(getStartHour(date)).append(SPACE);
                }
                else{
                    result.append(getStartHour(date) + COMMA + getEndHour(date)).append(SPACE);
                }
            }
            // 当即执行的状况
            else if(schedule.getGranularityPeriod().value() == 0){
                date = new Date(date.getTime() + 1000 * 60);
                result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE);
            }
            // 普通状况
            else{
                result.append(0).append(DIV).append(getValue(schedule.getGranularityPeriod())).append(SPACE)
                        .append(getHourTime(schedule)).append(SPACE);
            }

            return result.toString();
        }

        /**
         * trigger time return start Seconds
         */
        private int getStartSeconds(Date date) {

            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.SECOND);
        }

        /**
         * trigger time return start miniute
         */
        private int getStartMinute(Date date) {

            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.MINUTE);
        }

        /**
         * trigger time return start hour
         */
        private int getStartHour(Date date) {

            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.HOUR_OF_DAY);
        }

        /**
         * 得到日期的月数
         */
        private int getMonth(Date date) {
            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.MONTH) + 1;
        }

        /**
         * 得到日期的年数
         */
        private int getYear(Date date) {
            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.YEAR);
        }

        /**
         * 得到日期的天数
         */
        private int getDay(Date date) {
            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            return cal.get(Calendar.DAY_OF_MONTH);
        }

        /**
         * 获取12小时的结束时间
         * 
         * @param startHour
         * @return
         */
        private int getEndHour(Date date) {
            Calendar cal = new GregorianCalendar();
            cal.setTimeInMillis(date.getTime());
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            if(hour < 12){
                return 12 + hour;
            }
            return (12 + hour) % 24;
        }

        /**
         * 获得循环周期为月的具体的号数,假如输入的是1,那么就加入他所在位置的号数
         *  exp: input = "111110001001" output= "1,2,3,4,5,9,12";
         */
        private Object getByMonthDays(ScheduleInfo schedule) {

            String days = schedule.getMonthDays();
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < days.length(); i++){

                if("1".equals(days.charAt(i) + "")){

                    builder.append(i + 1).append(COMMA);
                }
            }
            String temp = builder.toString();
            if(temp.endsWith(COMMA)){

                return temp.substring(0, temp.length() - 1);
            }
            return temp;
        }

        /**
         * 获得循环周期为周的具体的星期天数, 例如输入的是1,
         * 那么就加入他所在位置的星期数 exp: input = "0001000"; output= "Wed";
         */
        public String getByWeekDays(ScheduleInfo schedule) {

            String days = schedule.getWeekDays();
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < days.length(); i++){

                if("1".equals(days.charAt(i) + "")){

                    builder.append(DayOfWeek.getDay(i)).append(COMMA);
                }
            }
            String temp = builder.toString();
            if(temp.endsWith(COMMA)){

                return temp.substring(0, temp.length() - 1);
            }
            return temp;
        }



        private String toDateCronExpr(ScheduleInfo schedule) {

            StringBuilder result = new StringBuilder();

            if(schedule.getGranularityPeriod().value() == 0){
                Date date = schedule.getStartTime();
                if(date == null)
                    date = new Date(System.currentTimeMillis());
                result.append(getDay(date)).append(SPACE).append(getMonth(date)).append(SPACE).append(INTERROGATION)
                        .append(SPACE).append(getYear(date));
            }
            else if("BY_DAY".equals(schedule.getDateCycle().toString())){

                result.append(ASTERISK).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
            }
            else if("BY_WEEK".equals(schedule.getDateCycle().toString())){

                result.append(INTERROGATION).append(SPACE).append(ASTERISK).append(SPACE).append(getByWeekDays(schedule));
            }
            else if("BY_MONTH".equals(schedule.getDateCycle().toString())){

                result.append(getByMonthDays(schedule)).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
            }

            return result.toString();
        }



        /**
         * 因为跨多个小时quartz不认,最大只能以小时为单位,因此只能对其进行转换。 
         * 如:0 0/240 * * ? 想以天天为单位,每隔4个小时触发一次,但状况仍是每一个小时触发一次。 只有将其改成 0 0/60
         * 0,4,8,12,16,20
         */
        public String getHourTime(ScheduleInfo schedule) {

            int hourUnit = schedule.getGranularityPeriod().value();

            String builder = null;

            if(hourUnit == 120){

                builder = "0,2,4,6,8,10,12,14,16,18,20,22";
            }
            else if(hourUnit == 180){

                builder = "0,3,6,9,12,15,18,21";
            }
            else if(hourUnit == 240){

                builder = "0,4,8,12,16,20";
            }
            else if(hourUnit == 360){

                builder = "0,6,12,18";
            }
            else if(hourUnit == 480){

                builder = "0,8,16";
            }
            else if(hourUnit == 720){

                builder = "0,12";
            }else{

                builder = "*";
            }
            return builder;
        }

        /**
         * 因为quartz的表达式最大支持为60分钟,所以,大于60就看成是60
         */
        public String getValue(GranularityPeriod value) {

            if(value.value() > 60){

                return "60";
            }

            return value.value() + "";
        }

}

6.设置定时任务(定时时间所要执行的任务)code

public class QuartzJob implements Job{

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        for(int i = 0; i < 5;i = i + 1){
            for(int j = 0; j < 3; j++){
                System.out.println("数组中的平均值"+j);
            }
            System.out.println("1111111");
        }        
    }

}

7.将定时任务添加到JobDetail中对象

public class QuartzManager {
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    
    /** 
     * @Description: 添加一个定时任务 
     *  
     * @param jobName 任务名 
     * @param jobGroupName  任务组名 
     * @param triggerName 触发器名 
     * @param triggerGroupName 触发器组名 
     * @param jobClass  任务 
     * @param cron   时间设置,参考quartz说明文档  
     */  
    @SuppressWarnings({ "rawtypes" })  
    public static void addJob(String jobName, String jobGroupName, Class jobClass, ScheduleInfo scheduleInfo) {  
        try {  
            //调度器
            Scheduler sched = schedulerFactory.getScheduler();  
            // 任务名,任务组,任务执行类
            JobDetail jobDetail= new JobDetail(jobName,jobGroupName,jobClass);

            // 建立Trigger对象   触发器
            CronTrigger cronTrigger = new CronTrigger(jobName,jobGroupName);
            cronTrigger.setStartTime(scheduleInfo.getStartTime());
            cronTrigger.setCronExpression(new CronTriggerUtil().toCronExpr(scheduleInfo));
            cronTrigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);

            sched.scheduleJob(jobDetail, cronTrigger);  

            // 启动  
            if (!sched.isShutdown()) {  
                sched.start();  
            } 
            
        } catch (Exception e) {  
        }  
    }  
    
    /** 
     * @Description: 开始一个定时任务
     */
    public static void startTimingJob(Integer jobType){
        UDCTimingSync timeSyncObj = new UDCTimingSync();
        timeSyncObj.setStatus(1);
        timeSyncObj.setSynctime("20:57:00");
        ScheduleInfo schedule_info = new ScheduleInfo();
        if(null == timeSyncObj.getStatus()){
            return;
        }
        if(timeSyncObj.getStatus().equals(UDCTimingSync.SWTICH_OFF)){
            return;
        }
        if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_DAY)){//按天
            schedule_info.setDateCycle(DateCycle.BY_DAY);
            schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
            schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
        }else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_WEEK)){//按周
            schedule_info.setDateCycle(DateCycle.BY_WEEK);
            schedule_info.setWeekDays(timeSyncObj.getWeek().toString());
            schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
            schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
        }else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_MONTH)){
            schedule_info.setDateCycle(DateCycle.BY_MONTH);
            schedule_info.setMonthDays(timeSyncObj.getDay().toString());
            schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
            schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
        }
        
        QuartzManager.addJob(UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobName(), 
                UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobGroupName(), QuartzJob.class, schedule_info);
    }
    
    /** 
     * @Description: 将传入的时间转成日历标准时间
     */
    public static Date getStartTime(String limitBeginTime) {
        Calendar calendar = Calendar.getInstance();

        // 获取当前时间
        Date currentDate = new Date(System.currentTimeMillis());
        calendar.setTime(currentDate);
        Date now = calendar.getTime();

        String[] begins = limitBeginTime.split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(begins[0]));
        calendar.set(Calendar.MINUTE, Integer.parseInt(begins[1]));
        calendar.set(Calendar.SECOND, Integer.parseInt(begins[2]));
        Date beginTime = calendar.getTime();

        // 当开始时间小于或者等于当前时间,则将日期增长一天
        boolean isGreater = beginTime.after(now);
        if (!isGreater) {
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }

        return calendar.getTime();
    }
}

8.测试类 调用定时任务

public class QuartzTest {

    public static void main(String[] args) {

        initJobs();
    }
    /** 
     * @Description: 调用定时任务组,传入定时任务组名
     */
private static void initJobs(){ QuartzManager.startTimingJob(UDCTimingSync.TYPE_IOPS); System.out.print("now time is"+new Date(System.currentTimeMillis())); } }
相关文章
相关标签/搜索