spring定时任务时间格式cronExpression设置
org.springframework.scheduling.quartz.CronTriggerBean允許你更精確地控制任務(wù)的運行時間,只需要設(shè)置其cronExpression屬性。
一個cronExpression表達式有至少6個(也可能是7個)由空格分隔的時間元素。從左至右,這些元素的定義如下:
1.秒(0–59)
2.分鐘(0–59)
3.小時(0–23)
4.月份中的日期(1–31)
5.月份(1–12或JAN–DEC)
6.星期中的日期(1–7或SUN–SAT)
7.年份(1970–2099)
0?0?10,14,16?*?*???每天上午10點,下午2點和下午4點
0?0,15,30,45?*?1-10?*???每月前10天每隔15分鐘
30?0?0?1?1???2012?在2012年1月1日午夜過30秒時
0?0?8-5???*?MON-FRI?每個工作日的工作時間?
各個時間可用值如下:
秒?0-59?,?–?*?/
分?0-59?,?–?*?/
小時?0-23?,?–?*?/
日?1-31?,?–?*???/?L?W?C
月?1-12?or?JAN-DEC?,?–?*?/
周幾?1-7?or?SUN-SAT?,?–?*???/?L?C?#
年?(可選字段)?empty,?1970-2099?,?–?*?/
可用值詳細分析如下:
“*”——字符可以用于所有字段,在“分”字段中設(shè)為”*”表示”每一分鐘”的含義。
“?”——字符可以用在“日”和“周幾”字段.?它用來指定?‘不明確的值’.?這在你需要指定這兩個字段中的某一個值而不是另外一個的時候會被用到。在后面的例子中可以看到其含義。
“-”——字符被用來指定一個值的范圍,比如在“小時”字段中設(shè)為”10-12″表示”10點到12點”。
“,”——字符指定數(shù)個值。比如在“周幾”字段中設(shè)為”MON,WED,FRI”表示”the?days?Monday,?Wednesday,?and?Friday”。
“/”——字符用來指定一個值的的增加幅度.?比如在“秒”字段中設(shè)置為”0/15″表示”第0,?15,?30,?和?45秒”。而?“5/15″則表示”第5,?20,?35,?和?50″.?在’/'前加”*”字符相當于指定從0秒開始.?每個字段都有一系列可以開始或結(jié)束的數(shù)值。對于“秒”和“分”字段來說,其數(shù)值范圍為0到59,對于“小時”字段來說其為0到23,?對于“日”字段來說為0到31,?而對于“月”字段來說為1到12。”/”字段僅僅只是幫助你在允許的數(shù)值范圍內(nèi)從開始”第n”的值。
“L”——字符可用在“日”和“周幾”這兩個字段。它是”last”的縮寫,?但是在這兩個字段中有不同的含義。例如,“日”字段中的”L”表示”一個月中的最后一天”?——?對于一月就是31號對于二月來說就是28號(非閏年)。而在“周幾”字段中,?它簡單的表示”7″?or?“SAT”,但是如果在“周幾”字段中使用時跟在某個數(shù)字之后,?它表示”該月最后一個星期×”?——?比如”6L”表示”該月最后一個周五”。當使用’L'選項時,指定確定的列表或者范圍非常重要,否則你會被結(jié)果搞糊涂的。
“W”——可用于“日”字段。用來指定歷給定日期最近的工作日(周一到周五)?。比如你將“日”字段設(shè)為”15W”,意為:?“離該月15號最近的工作日”。因此如果15號為周六,觸發(fā)器會在14號即周五調(diào)用。如果15號為周日,?觸發(fā)器會在16號也就是周一觸發(fā)。如果15號為周二,那么當天就會觸發(fā)。然而如果你將“日”字段設(shè)為”1W”,?而一號又是周六,?觸發(fā)器會于下周一也就是當月的3號觸發(fā),因為它不會越過當月的值的范圍邊界。’W'字符只能用于“日”字段的值為單獨的一天而不是一系列值的時候。
“L”和“W”可以組合用于“日”字段表示為’LW’,意為”該月最后一個工作日”。
“#”——?字符可用于“周幾”字段。該字符表示“該月第幾個周×”,比如”6#3″表示該月第三個周五(?6表示周五而”#3″該月第三個)。再比如:?“2#1″?=?表示該月第一個周一而?“4#5″?=?該月第五個周三。注意如果你指定”#5″該月沒有第五個“周×”,該月是不會觸發(fā)的。
“C”——?字符可用于“日”和“周幾”字段,它是”calendar”的縮寫。?它表示為基于相關(guān)的日歷所計算出的值(如果有的話)。如果沒有關(guān)聯(lián)的日歷,?那它等同于包含全部日歷。“日”字段值為”5C”表示”日歷中的第一天或者5號以后”,“周幾”字段值為”1C”則表示”日歷中的第一天或者周日以后”。
對于“月份”字段和“周幾”字段來說合法的字符都不是大小寫敏感的。
一些例子:
關(guān)于cronExpression表達式: 字段 允許值 允許的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小時 0-23 , - * / 日期 1-31 , - * ? / L W C 月份 1-12 或者 JAN-DEC , - * / 星期 1-7 或者 SUN-SAT , - * ? / L C # 年(可選) 留空, 1970-2099 , - * / 表達式意義 "0 0 12 * * ?" 每天中午12點觸發(fā) "0 15 10 ? * *" 每天上午10:15觸發(fā) "0 15 10 * * ?" 每天上午10:15觸發(fā) "0 15 10 * * ? *" 每天上午10:15觸發(fā) "0 15 10 * * ? 2005" 2005年的每天上午10:15觸發(fā) "0 * 14 * * ?" 在每天下午2點到下午2:59期間的每1分鐘觸發(fā) "0 0/5 14 * * ?" 在每天下午2點到下午2:55期間的每5分鐘觸發(fā) "0 0/5 14,18 * * ?" 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發(fā) "0 0-5 14 * * ?" 在每天下午2點到下午2:05期間的每1分鐘觸發(fā) "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44觸發(fā) "0 15 10 ? * MON-FRI" 周一至周五的上午10:15觸發(fā) "0 15 10 15 * ?" 每月15日上午10:15觸發(fā) "0 15 10 L * ?" 每月最后一日的上午10:15觸發(fā) "0 15 10 ? * 6L" 每月的最后一個星期五上午10:15觸發(fā) "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一個星期五上午10:15觸發(fā) "0 15 10 ? * 6#3" 每月的第三個星期五上午10:15觸發(fā) 每天早上6點 0 6 * * * 每兩個小時 0 */2 * * * 晚上11點到早上8點之間每兩個小時,早上八點 0 23-7/2,8 * * * 每個月的4號和每個禮拜的禮拜一到禮拜三的早上11點 0 11 4 * 1-3 1月1日早上4點 0 4 1 1 *
Quartz?在Spring中動態(tài)設(shè)置cronExpression
什么是動態(tài)定時任務(wù):是由客戶制定生成的,服務(wù)端只知道該去執(zhí)行什么任務(wù),但任務(wù)的定時是不確定的(是由客戶制定)。
這樣總不能修改配置文件每定制個定時任務(wù)就增加一個trigger吧,即便允許客戶修改配置文件,但總需要重新啟動web服務(wù)啊,研究了下Quartz在Spring中的動態(tài)定時,發(fā)現(xiàn)<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
?????????<property name="jobDetail" ref="schedulerJobDetail"/>
?????????<property name="cronExpression">
?????????????<value>0/10 * * * * ?</value>
?????????</property>
??????中cronExpression是關(guān)鍵,如果可以動態(tài)設(shè)置cronExpression的值,也就說如果我們可以直接調(diào)用CronTriggerBean中設(shè)置cronExpression的方法,就可以順利解決問題了。
熟悉1的朋友可以跳過不看,下面2、3是動態(tài)定時任務(wù)的具體實現(xiàn)。
?
1.??Quartz?在Spring中的簡單配置
Spring?配置文件:
????<bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
????????<property name="targetObject" ref="scheduleInfoAction"/>
????????<property name="targetMethod" value="simpleJobTest"/>
????????<property name="concurrent" value="false"/>
????</bean>
????<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
?????????<property name="jobDetail" ref="schedulerJobDetail"/>
?????????<property name="cronExpression">
?????????????<value>0/10 * * * * ?</value>
?????????</property>
?????</bean>
????<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
????????<property name="triggers">
????????????<list>
????????????????<ref local="cronTrigger"/>
????????????</list>
????????</property>
</bean>
?
在上面的配置中設(shè)定了
①?targetMethod:?指定需要定時執(zhí)行scheduleInfoAction中的simpleJobTest()方法
②?concurrent:對于相同的JobDetail,當指定多個Trigger時,?很可能第一個job完成之前,第二個job就開始了。指定concurrent設(shè)為false,多個job不會并發(fā)運行,第二個job將不會在第一個job完成之前開始。
③?cronExpression:0/10 * * * * ?表示每10秒執(zhí)行一次,具體可參考附表。
④?triggers:通過再添加其他的ref元素可在list中放置多個觸發(fā)器。
?
scheduleInfoAction?中的simpleJobTest()方法
注意:此方法沒有參數(shù),如果scheduleInfoAction有兩個方法simpleJobTest()和simpleJobTest(String argument),則spring只會去執(zhí)行無參的simpleJobTest().
public void?simpleJobTest() {?
????????log.warn("uh oh, Job is scheduled !'" + "' Success...");
????}
?
2?.Quartz在Spring中動態(tài)設(shè)置cronTrigger方法一
Spring?配置文件:
<bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">
????????<property name="scheduler" ref="schedulerFactory"/>
????????<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
????</bean>
????<bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
????????<property name="targetObject" ref="scheduleInfoAction"/>
????????<property name="targetMethod" value="reScheduleJob"/>
????????<property name="concurrent" value="false"/>
????</bean>
????<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
?????????<property name="jobDetail" ref="schedulerJobDetail"/>
?????????<property name="cronExpression">
?????????????<value>0/10 * * * * ?</value>
?????????</property>
?????</bean>
????<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
????????<property name="triggers">
????????????<list>
????????????????<ref local="cronTrigger"/>
????????????</list>
????????</property>
</bean>
?
scheduleInfoAction?中的reScheduleJob?()方法及相關(guān)方法
①?reScheduleJob():讀取數(shù)據(jù)庫,獲得自定義定時器調(diào)度時間
????private void?reScheduleJob() throws SchedulerException, ParseException {
????????//?運行時可通過動態(tài)注入的scheduler得到trigger
????????CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(
?????????????????"cronTrigger", Scheduler.DEFAULT_GROUP);
????????String dbCronExpression =?getCronExpressionFromDB();
????????String originConExpression = trigger.getCronExpression();
????//?判斷從DB中取得的任務(wù)時間(dbCronExpression)和現(xiàn)在的quartz線程中的任務(wù)時間(originConExpression)是否相等
????//?如果相等,則表示用戶并沒有重新設(shè)定數(shù)據(jù)庫中的任務(wù)時間,這種情況不需要重新rescheduleJob
????????if(!originConExpression.equalsIgnoreCase(dbCronExpression)){
????????????trigger.setCronExpression(dbCronExpression);
????????????scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, trigger);
????????}
????//?下面是具體的job內(nèi)容,可自行設(shè)置
????// executeJobDetail();
}
?
②?getCronExpressionFromDB():從數(shù)據(jù)庫中獲得dbCronExpression的具體代碼,由于使用了scheduleInfoManager,所以要在定義相應(yīng)的setter方法
????private String?getCronExpressionFromDB(){
????????String sql="from ScheduleInfo scheduleInfo where 1=1 ";
????????sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";
????????List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);
????????ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);
????????String dbCronExpression = scheduleInfo.getCronExpression();
????????return dbCronExpression;
}
?
③ 在spring配置文件的scheduleInfoAction配置了相應(yīng)的property(scheduler/scheduleInfoManager),要為其設(shè)置setter方法
????private Scheduler scheduler;
????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實例scheduler
????public void?setScheduler(Scheduler scheduler) {
????????this.scheduler = scheduler;
?????}
????private ScheduleInfoManager scheduleInfoManager;
????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實例scheduleInfoManager
????public void?setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
????????this.scheduleInfoManager = scheduleInfoManager;
????}
?
3.??Quartz?在Spring中動態(tài)設(shè)置cronTrigger方法二
在上面的2中我們可以看到,盡管?已經(jīng)可以動態(tài)進行?rescheduleJob?了,不過依然需要我們設(shè)置一個?cronExpression?,如果嘗試一下拿掉spring配置中的
????????<property name="cronExpression">
?????????????<value>0/10 * * * * ?</value>
?????????</property>
則容器(如tomcat)啟動時會報錯。
實際中我們希望tomcat啟動時就可以直接去讀數(shù)據(jù)庫,拿到相應(yīng)的?dbCronExpression?,然后定時執(zhí)行一個job,而不希望配置初始的?cronExpression?,觀察下面的?CronTriggerBean?,考慮到cronExpression需要初始化,如果設(shè)定一個類InitializingCronTrigger繼承CronTriggerBean,然后在這個類中做一些讀取DB的初始化工作(設(shè)置cronExpression),問題就可以解決了。
?
Spring?配置文件:
<bean id="scheduleInfoAction" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction">
????????<property name="scheduler" ref="schedulerFactory"/>
????????<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
????</bean>
????<bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
????????<property name="targetObject" ref="scheduleInfoAction"/>
????????<property name="targetMethod" value="reScheduleJob"/>
????????<property name="concurrent" value="false"/>
????</bean>
?????<bean id="cronTrigger" class="com.lively.happyoa.jobs.webapp.action.ScheduleInfoAction.InitializingCronTrigger">
?????????<property name="jobDetail" ref="schedulerJobDetail"/>
?????????<!--<property name="cronExpression">
?????????????<value>0/10 * * * * ?</value>
?????????</property>-->
?????????<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
?????</bean>
????<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
????????<property name="triggers">
????????????<list>
????????????????<ref local="cronTrigger"/>
????????????</list>
????????</property>
</bean>
?
InitializingCronTrigger?中的相關(guān)方法
注意:在注入scheduleInfoManager屬性的時候,我們可以去讀取DB任務(wù)時間(之所以放在setter方法中,是因為需要在設(shè)置scheduleInfoManager后進行g(shù)etCronExpressionFromDB(),否則,也可以①②邏輯把放在類的構(gòu)造函數(shù)中).
注意InitializingCronTrigger必須extendsCronTriggerBean.
?
public class InitializingCronTrigger?extendsCronTriggerBean?implements Serializable {
????private ScheduleInfoManager scheduleInfoManager;
????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實例scheduleInfoManager
????public void?setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
????????this.scheduleInfoManager = scheduleInfoManager;
????????//?因為在getCronExpressionFromDB使用到了scheduleInfoManager,所以
????????//?必須上一行代碼設(shè)置scheduleInfoManager后進行g(shù)etCronExpressionFromDB
????????String cronExpression =?getCronExpressionFromDB?();???//?①
????????//?因為extendsCronTriggerBean?,此處調(diào)用父類方法初始化cronExpression
????????setCronExpression?(cronExpression);????????????????????//?②
}
????private String?getCronExpressionFromDB(){
????????String sql="from ScheduleInfo scheduleInfo where 1=1 ";
????????sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";
????????List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);
????????ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);
????????String dbCronExpression = scheduleInfo.getCronExpression();
????????return dbCronExpression;
?}
……
}
總結(jié)
以上是生活随笔為你收集整理的spring定时任务时间格式cronExpression设置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 11g备份,导入oracl
- 下一篇: weblogic11g集群配置