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())); } }
相關文章
相關標籤/搜索