使用quartz開源調度框架,寫服務實現在一些指定場景發送特定短信,創建一個實現org.quartz.Job接口的java類。Job接口包含唯一的方法:
public void execute(JobExecutionContext context) throws JobExecutionException;
在你的Job接口實現類里面,添加一些邏輯到
execute()方法。一旦你配置好Job實現類並設定好調度時間表,Quartz將密切注意剩余時間。當調度程序確定該是通知你的作業的時候,
Quartz框架將調用你Job實現類(作業類)上的
execute()方法並允許做它該做的事情。無需報告任何東西給調度器或調用任何特定的東西。僅僅
執行任務和結束任務即可。如果配置你的作業在隨后再次被調用,Quartz框架將
在恰當的時間再次調用它;
存放調度器(Job 和 Trigger)信息的xml配置文件中:
<!-- 實時掃描短信數據表,沒有發送的調用運營商給的接口推送,完成發送短信操作 --> <job> <name>ReceiveMessageJob</name> <job-class>com.xxx.cscns.sms.ReceiveMessageJob</job-class> </job> <trigger> <simple> <name>ReceiveMessageJob</name> <job-name>ReceiveMessageJob</job-name> <repeat-count>-1</repeat-count> <repeat-interval>1</repeat-interval> </simple> </trigger>
<!-- 每天給項目經理發送短信避免短信服務掛了 定時每天08:30執行--> <job> <name>SendToManagerJob</name> <job-class>com.xxx.cscns.sms.SendToManagerJob</job-class> </job> <trigger> <cron> <name>SendToManagerJob</name> <job-name>SendToManagerJob</job-name> <cron-expression>0 30 8 * * ?</cron-expression> </cron> </trigger>
其中<cron-expression>標簽的值表示執行的時間和頻率信息,有一套完整的格式規范:
序號 說明 是否必填 允許填寫的值 允許的通配符
1 秒 是 0-59 , - * /
2 分 是 0-59 , - * /
3 小時 是 0-23 , - * /
4 日 是 1-31 , - * ? / L W
5 月 是 1-12 or JAN-DEC , - * /
6 周 是 1-7 or SUN-SAT , - * ? / L #
7 年 否 empty 或 1970-2099 , - * /
上面短信發送任務的 0 30 8 * * ? 表示“每天早上八點半執行一次”的意思;
其中通配符說明:* 表示所有值,例如:在分的字段上設置 "*",表示每一分鍾都會觸發;
? 表示不指定值。使用的場景為不需要關心當前設置這個字段的值。例如:要在每月的10號觸發一個操作,但不關心是周幾,所以需要周位置的那個字段設置為"?" ;
- 表示區間。例如 在小時上設置 "10-12",表示 10,11,12點都會觸發。, 表示指定多個值,例如在周字段上設置 "MON,WED,FRI" 表示周一,周三和周五觸發 ;
/ 用於遞增觸發。如在秒上面設置"5/15" 表示從5秒開始,每增15秒觸發(5,20,35,50)。 在日字段上設置'1/3'所示每月1號開始,每隔三天觸發一次 ;
L 表示最后的意思。在日字段設置上,表示當月的最后一天(依據當前月份,如果是二月還會依據是否是潤年[leap]), 在周字段上表示星期六,相當於"7"或"SAT",
如果在"L"前加上數字,則表示該數據的最后一個。例如在周字段上設置"6L"這樣的格式,則表示“本月最后一個星期五",因為7是星期六,1是星期日;
W 表示離指定日期的最近那個工作日(周一至周五). 例如在日字段上設置"15W",表示離每月15號最近的那個工作日觸發;
'L'和 'W'可以一組合使用。如果在日字段上設置"LW",則表示在本月的最后一個工作日觸發;
**簡單和復雜的配置job和trigger:
simple 簡單任務的觸發器,可以調度用於重復執行的任務 name(必填) 觸發器名稱,同一個分組中的名稱必須不同 group(選填) 觸發器組 description(選填) 觸發器描述 job-name(必填) 要調度的任務名稱,該job-name必須和對應job節點中的name完全相同 job-group(選填) 調度任務(job)所屬分組,該值必須和job中的group完全相同 start-time(選填) 任務開始執行時間utc時間,北京時間需要+08:00,如:<start-time>2012-04-01T08:00:00+08:00</start-time>表示北京時間2012年4月1日上午8:00開始執行,注意服務啟動或重啟時都會檢測此屬性,若沒有設置此屬性或者start-time設置的時間比當前時間較早,則服務啟動后會立即執行一次調度,若設置的時間比當前時間晚,服務會等到設置時間相同后才會第一次執行任務,一般若無特殊需要請不要設置此屬性 repeat-count(必填) 任務執行次數,如:<repeat-count>-1</repeat-count>表示無限次執行,<repeat-count>10</repeat-count>表示執行10次 repeat-interval(必填) 任務觸發間隔(毫秒),如:<repeat-interval>10000</repeat-interval> 每10秒執行一次
cron復雜任務觸發器--使用cron表達式定制任務調度(強烈推薦) name(必填) 觸發器名稱,同一個分組中的名稱必須不同 group(選填) 觸發器組 description(選填) 觸發器描述 job-name(必填) 要調度的任務名稱,該job-name必須和對應job節點中的name完全相同 job-group(選填) 調度任務(job)所屬分組,該值必須和job中的group完全相同 start-time(選填) 任務開始執行時間utc時間,北京時間需要+08:00,如:<start-time>2012-04-01T08:00:00+08:00</start-time>表示北京時間2012年4月1日上午8:00開始執行,注意服務啟動或重啟時都會檢測此屬性,若沒有設置此屬性,服務會根據cron-expression的設置執行任務調度;若start-time設置的時間比當前時間較早,則服務啟動后會忽略掉cron-expression設置,立即執行一次調度,之后再根據cron-expression執行任務調度;若設置的時間比當前時間晚,則服務會在到達設置時間相同后才會應用cron-expression,根據規則執行任務調度,一般若無特殊需要請不要設置此屬性 cron-expression(必填) cron表達式,如:<cron-expression>0/10 * * * * ?</cron-expression>每10秒執行一次
根據配置的調度信息,找到job的實現類和其業務邏輯實施層方法,如下實例:
job實現類的代碼:
package com.xxx.cscns.sms; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.xxx.core.xxxFrameDsManager; import com.xxx.cscns.service.MessageService; @DisallowConcurrentExecution public class SendToManagerJob implements Job{ @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { try { xxxFrameDsManager.begin(null); MessageService messageService = new MessageService(); // 調用業務邏輯實施層方法,實現發短信操作 messageService.sendToManger(); System.out.println("上班前半小時發送一次短信給項目經理成功!"); } catch (Exception e) { xxxFrameDsManager.rollback(); e.printStackTrace(); System.out.println("上班前半小時發送一次短信給項目經理異常:"+e.toString()); } finally { xxxFrameDsManager.close(); } } }
封裝的業務邏輯實施層的方法:
/* * * 每天給項目經理發送短信避免短信服務掛了 */ public void sendToManger() { try { //系統參數配置項目經理手機號碼,這兒是封裝的方法,只要能獲取到項目經理手機號就行 String messageTarget = new FrameConfigService9().getFrameConfigValue("ASP_MESSAGE_TEST_TEL"); //時間格式化 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String sql = "insert into Messages_center ( MessageItemGuid, Content, GenerateDate, IsSchedule, MessageTarget, sendMode,messagetype)"; sql += "values( '" + UUID.randomUUID().toString() + "', '【XXX項目】短信服務正常。', to_date('" + sdf2.format(new Date())+ "', 'yyyy-mm-dd hh24:mi:ss'), 0, '" + messageTarget + "', 1,'短信')"; if(StringUtil.isNotBlank(messageTarget)){ dao.execute(sql); } } catch (Exception e) { e.printStackTrace(); dao.rollBackTransaction(); } finally { if (dao != null){ dao.close(); } } }