日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Quartz在Spring中设置动态定时任务 .

發(fā)布時(shí)間:2025/7/14 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Quartz在Spring中设置动态定时任务 . 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
什么是動(dòng)態(tài)定時(shí)任務(wù):
是由客戶制定生成的,服務(wù)端只知道該去執(zhí)行什么任務(wù),但任務(wù)的定時(shí)是不確定的(是由客戶制定)。這樣總不能修改配置文件每定制個(gè)定時(shí)任務(wù)就增加一個(gè)trigger吧,即便允許客戶修改配置文件,但總需要重新啟動(dòng)web服務(wù)啊,研究了下Quartz在Spring中的動(dòng)態(tài)定時(shí),發(fā)現(xiàn): cronExpression是關(guān)鍵,如果可以動(dòng)態(tài)設(shè)置cronExpression的值,也就說如果我們可以直接調(diào)用CronTriggerBean中設(shè)置cronExpression的方法,就可以順利解決問題了。
① targetMethod: 指定需要定時(shí)執(zhí)行scheduleInfoManager中的simpleJobTest()方法
② concurrent:對(duì)于相同的JobDetail,當(dāng)指定多個(gè)Trigger時(shí), 很可能第一個(gè)job完成之前,第二個(gè)job就開始了。指定concurrent設(shè)為false,多個(gè)job不會(huì)并發(fā)運(yùn)行,第二個(gè)job將不會(huì)在第一個(gè)job完成之前開始。
③ cronExpression:0/10 * * * * ?表示每10秒執(zhí)行一次,具體可參考附表。
④ triggers:通過再添加其他的ref元素可在list中放置多個(gè)觸發(fā)器。scheduleInfoManager中的simpleJobTest()方法注意:此方法沒有參數(shù),如果scheduleInfoManager有兩個(gè)方法simpleJobTest()和simpleJobTest(String argument),則spring只會(huì)去執(zhí)行無參的simpleJobTest().
public void simpleJobTest()
{?????????
?? log.warn("uh oh, Job is scheduled !'" + "' Success...");????
}
?? Quartz在Spring中動(dòng)態(tài)設(shè)置cronTrigger方法一Spring配置文件:
將定時(shí)器注入到業(yè)務(wù)邏輯層Manager
Xml代碼
  • <bean?id="scheduleInfoManager"?class="com.lively.happyoa.jobs.webapp.manager.scheduleInfoManager">??
  • ?????????<property?name="scheduler"?ref="schedulerFactory"/>??
  • ?????</bean>??
  • ?????<bean?id="schedulerJobDetail"?class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">??
  • ?????????<property?name="targetObject"?ref="scheduleInfoManager"/>??
  • ?????????<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>??

  • scheduleInfoManager中的reScheduleJob ()方法及相關(guān)方法① reScheduleJob讀取數(shù)據(jù)庫,獲得自定義定時(shí)器調(diào)度時(shí)間():
    Java代碼
  • private?Scheduler?scheduler;? ??
  • ??
  • //?設(shè)值注入,通過setter方法傳入被調(diào)用者的實(shí)例scheduler??
  • public?void?setScheduler(Scheduler?scheduler)?{??? ??
  • ?????this.scheduler?=?scheduler;??? ??
  • }??? ??
  • rivate?void?reScheduleJob()?throws?SchedulerException,ParseException?{ ??
  • ????????//?運(yùn)行時(shí)可通過動(dòng)態(tài)注入的scheduler得到trigger,注意采用這種注入方式在有的項(xiàng)目中會(huì)有問題,如果遇到注入問題,可以采取在運(yùn)行方法時(shí)候,獲得bean來避免錯(cuò)誤發(fā)生。??
  • ????????CronTriggerBean?trigger?=?(CronTriggerBean)?scheduler.getTrigger(????????????????"cronTrigger",?Scheduler.DEFAULT_GROUP); ??
  • ????????String?dbCronExpression?=?getCronExpressionFromDB(); ??
  • ????????String?originConExpression?=?trigger.getCronExpression(); ??
  • ????//?判斷從DB中取得的任務(wù)時(shí)間(dbCronExpression)和現(xiàn)在的quartz線程中的任務(wù)時(shí)間(originConExpression)是否相等??
  • ????//?如果相等,則表示用戶并沒有重新設(shè)定數(shù)據(jù)庫中的任務(wù)時(shí)間,這種情況不需要重新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方法:
    Java代碼
  • 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配置文件的scheduleInfoManager配置了相應(yīng)的property(scheduler/ Java代碼
  • scheduleInfoManager),要為其設(shè)置setter方法:? ??
  • private?Scheduler?scheduler; ??
  • ?????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實(shí)例scheduler??
  • ?????public?void?setScheduler(Scheduler?scheduler)?{ ??
  • ?????????this.scheduler?=?scheduler; ??
  • ????} ??
  • ?????private?ScheduleInfoManager?scheduleInfoManager; ??
  • ?????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實(shí)例scheduleInfoManager??
  • ?????public?void?setScheduleInfoManager(ScheduleInfoManager?scheduleInfoManager){ ??
  • ?????????this.scheduleInfoManager?=?scheduleInfoManager; ??
  • ?????} ?

  • Quartz在Spring中動(dòng)態(tài)設(shè)置cronTrigger方法二在上面的2中我們可以看到,盡管已經(jīng)可以動(dòng)態(tài)進(jìn)行rescheduleJob了,不過依然需要我們?cè)O(shè)置一個(gè)cronExpression,如果嘗試一下拿掉spring配置中的????????
    <property name="cronExpression">
    ????????????? <value>0/10 * * * * ?</value>
    </property>
    則容器(如tomcat)啟動(dòng)時(shí)會(huì)報(bào)錯(cuò)。實(shí)際中我們希望tomcat啟動(dòng)時(shí)就可以直接去讀數(shù)據(jù)庫,拿到相應(yīng)的dbCronExpression,然后定時(shí)執(zhí)行一個(gè)job,而不希望配置初始的cronExpression ,觀察下面的CronTriggerBean,考慮到cronExpression需要初始化,如果設(shè)定一個(gè)類InitializingCronTrigger繼承CronTriggerBean,然后在這個(gè)類中做一些讀取DB的初始化工作(設(shè)置cronExpression),問題就可以解決了。Spring配置文件:
    Xml代碼
  • <bean?id="scheduleInfoManager"?class="com.lively.happyoa.jobs.webapp.manager.ScheduleInfoManager">?????????<property?name="scheduler"?ref="schedulerFactory"/>??
  • ?????</bean>??
  • ?????<bean?id="schedulerJobDetail"?class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">??
  • ?????????<property?name="targetObject"?ref="scheduleInfoManager"/>??
  • ?????????<property?name="targetMethod"?value="reScheduleJob"/>??
  • ?????????<property?name="concurrent"?value="false"/>??
  • ?????</bean>??
  • ????<bean?id="cronTrigger"?class="com.lively.happyoa.jobs.webapp.manager.ScheduleInfoManager.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屬性的時(shí)候,我們可以去讀取DB任務(wù)時(shí)間(之所以放在setter方法中,是因?yàn)樾枰谠O(shè)置scheduleInfoManager后進(jìn)行g(shù)etCronExpressionFromDB(),否則,也可以①②邏輯把放在類的構(gòu)造函數(shù)中).注意InitializingCronTrigger必須extends CronTriggerBean.
    Java代碼
  • public?class?InitializingCronTrigger?extends?CronTriggerBean?implements?Serializable?{ ??
  • ?????private?ScheduleInfoManager?scheduleInfoManager; ??
  • ?????//?設(shè)值注入,通過setter方法傳入被調(diào)用者的實(shí)例scheduleInfoManager??
  • ?????public?void?setScheduleInfoManager(ScheduleInfoManager?scheduleInfoManager){ ??
  • ?????????this.scheduleInfoManager?=?scheduleInfoManager; ??
  • ?????????//?因?yàn)樵趃etCronExpressionFromDB使用到了scheduleInfoManager,所以??
  • ?????????//?必須上一行代碼設(shè)置scheduleInfoManager后進(jìn)行??
  • getCronExpressionFromDB ??
  • ?????????String?cronExpression?=?getCronExpressionFromDB?(); ??
  • ????//?① ??
  • ?????????//?因?yàn)閑xtends?CronTriggerBean?,此處調(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;}……} ?
  • Quartz中時(shí)間參數(shù)說明 即Cron表達(dá)式
    Cron表達(dá)式
    Quartz使用類似于Linux下的Cron表達(dá)式定義時(shí)間規(guī)則,Cron表達(dá)式由6或7個(gè)由空格分隔的時(shí)間字段組成,如表1所示:

    表1 Cron表達(dá)式時(shí)間字段

    位置
    ?
    時(shí)間域名 允許值 允許的特殊字符
    ?
    ?
    ?
    1 秒 0-59 , - * /
    ?
    2 分鐘 0-59 , - * /
    ?
    3 小時(shí) 0-23 , - * /
    ?
    4 日期 1-31 , - * ? / L W C
    ?
    5 月份 1-12 , - * /
    ?
    6 星期 1-7 , - * ? / L C #
    ?
    7 年(可選) 空值1970-2099 , - * /


    Cron表達(dá)式的時(shí)間字段除允許設(shè)置數(shù)值外,還可使用一些特殊的字符,提供列表、范圍、通配符等功能,細(xì)說如下:

    ●星號(hào)(*):可用在所有字段中,表示對(duì)應(yīng)時(shí)間域的每一個(gè)時(shí)刻,例如,*在分鐘字段時(shí),表示“每分鐘”;

    ●問號(hào)(?):該字符只在日期和星期字段中使用,它通常指定為“無意義的值”,相當(dāng)于點(diǎn)位符;

    ●減號(hào)(-):表達(dá)一個(gè)范圍,如在小時(shí)字段中使用“10-12”,則表示從10到12點(diǎn),即10,11,12;

    ●逗號(hào)(,):表達(dá)一個(gè)列表值,如在星期字段中使用“MON,WED,FRI”,則表示星期一,星期三和星期五;

    ●斜杠(/):x/y表達(dá)一個(gè)等步長(zhǎng)序列,x為起始值,y為增量步長(zhǎng)值。如在分鐘字段中使用0/15,則表示為0,15,30和45秒,而5/15在分鐘字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;

    ●L:該字符只在日期和星期字段中使用,代表“Last”的意思,但它在兩個(gè)字段中意思不同。L在日期字段中,表示這個(gè)月份的最后一天,如一月的31號(hào),非閏年二月的28號(hào);如果L用在星期中,則表示星期六,等同于7。但是,如果L出現(xiàn)在星期字段里,而且在前面有一個(gè)數(shù)值X,則表示“這個(gè)月的最后X天”,例如,6L表示該月的最后星期五;

    ●W:該字符只能出現(xiàn)在日期字段里,是對(duì)前導(dǎo)日期的修飾,表示離該日期最近的工作日。例如15W表示離該月15號(hào)最近的工作日,如果該月15號(hào)是星期六,則匹配14號(hào)星期五;如果15日是星期日,則匹配16號(hào)星期一;如果15號(hào)是星期二,那結(jié)果就是15號(hào)星期二。但必須注意關(guān)聯(lián)的匹配日期不能夠跨月,如你指定1W,如果1號(hào)是星期六,結(jié)果匹配的是3號(hào)星期一,而非上個(gè)月最后的那天。W字符串只能指定單一日期,而不能指定日期范圍;

    ●LW組合:在日期字段可以組合使用LW,它的意思是當(dāng)月的最后一個(gè)工作日;

    ●井號(hào)(#):該字符只能在星期字段中使用,表示當(dāng)月某個(gè)工作日。如6#3表示當(dāng)月的第三個(gè)星期五(6表示星期五,#3表示當(dāng)前的第三個(gè)),而4#5表示當(dāng)月的第五個(gè)星期三,假設(shè)當(dāng)月沒有第五個(gè)星期三,忽略不觸發(fā);

    ● C:該字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是計(jì)劃所關(guān)聯(lián)的日期,如果日期沒有被關(guān)聯(lián),則相當(dāng)于日歷中所有日期。例如5C在日期字段中就相當(dāng)于日歷5日以后的第一天。1C在星期字段中相當(dāng)于星期日后的第一天。

    Cron表達(dá)式對(duì)特殊字符的大小寫不敏感,對(duì)代表星期的縮寫英文大小寫也不敏感。

    表2下面給出一些完整的Cron表示式的實(shí)例:

    表2 Cron表示式示例

    表示式
    說明
    ?
    ?
    "0 0 12 * * ? " 每天12點(diǎn)運(yùn)行
    ?
    "0 15 10 ? * *" 每天10:15運(yùn)行
    ?
    "0 15 10 * * ?" 每天10:15運(yùn)行
    ?
    "0 15 10 * * ? *" 每天10:15運(yùn)行
    ?
    "0 15 10 * * ? 2008" 在2008年的每天10:15運(yùn)行
    ?
    "0 * 14 * * ?" 每天14點(diǎn)到15點(diǎn)之間每分鐘運(yùn)行一次,開始于14:00,結(jié)束于14:59。
    ?
    "0 0/5 14 * * ?" 每天14點(diǎn)到15點(diǎn)每5分鐘運(yùn)行一次,開始于14:00,結(jié)束于14:55。
    ?
    "0 0/5 14,18 * * ?" 每天14點(diǎn)到15點(diǎn)每5分鐘運(yùn)行一次,此外每天18點(diǎn)到19點(diǎn)每5鐘也運(yùn)行一次。
    ?
    "0 0-5 14 * * ?" 每天14:00點(diǎn)到14:05,每分鐘運(yùn)行一次。
    ?
    "0 10,44 14 ? 3 WED" 3月每周三的14:10分到14:44,每分鐘運(yùn)行一次。
    ?
    "0 15 10 ? * MON-FRI" 每周一,二,三,四,五的10:15分運(yùn)行。
    ?
    "0 15 10 15 * ?" 每月15日10:15分運(yùn)行。
    ?
    "0 15 10 L * ?" 每月最后一天10:15分運(yùn)行。
    ?
    "0 15 10 ? * 6L" 每月最后一個(gè)星期五10:15分運(yùn)行。
    ?
    "0 15 10 ? * 6L 2007-2009" 在2007,2008,2009年每個(gè)月的最后一個(gè)星期五的10:15分運(yùn)行。
    ?
    "0 15 10 ? * 6#3" 每月第三個(gè)星期五的10:15分運(yùn)行。
    ?
    ?


    注意:CronTriggerBean的cronExpression屬性指定格式:至少6個(gè)時(shí)間元素,上面表示每天的15:37-38分執(zhí)行1次任務(wù)。

    時(shí)間元素(按照順序):

    秒(0-59):

    分(0-59):

    小時(shí)(0-23):

    每月第幾天(1-31):

    月(1-12或JAN-DEC):

    每星期第幾天(1-7或SUN-SAT):

    年(1970-2099):

    其中:不用設(shè)置的用”?”.

    (1)每月第幾天和每星期第幾天是互斥的,兩個(gè)只能設(shè)置1個(gè)。如果有好幾個(gè)時(shí)間點(diǎn),可以使用”,”符號(hào),例如:”0 0 10,12,14 * * ?”表示每天的10時(shí),12時(shí),14時(shí)執(zhí)行Job.

    (2)對(duì)于連續(xù)時(shí)間可以使用”-”符號(hào)。例如:”0 10,12,14 1-15 * ?”表示每月的1到15日10時(shí),12時(shí),14時(shí)執(zhí)行Job.

    (3)時(shí)間格式的年可以不用制定。例如”0 0 10,12,14 ? MON 2006”表示2006年每星期一的10時(shí),12時(shí),14時(shí)執(zhí)行Job.?

    總結(jié)

    以上是生活随笔為你收集整理的Quartz在Spring中设置动态定时任务 .的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。