兩種方式部署定時任務(wù),Spring整合Quartz倦蚪,Spring整合task(java后臺)

(Notice:以下所有經(jīng)驗也是我根據(jù)網(wǎng)上的經(jīng)驗整理的希坚,如有侵權(quán)可以聯(lián)系我刪除,歡迎交流和溝通陵且,Wx:IT_Ezra裁僧,QQ 654303408个束。 有問題討論也可聯(lián)系我。)

(Tips:我是第一次開發(fā)聊疲,一個剛畢業(yè)的java工程師茬底,我覺得我并非天賦異稟,我能學(xué)會获洲,相信聰敏的你阱表,一定可以)

(PS:定時任務(wù)是一個非常常見的功能,在我們進(jìn)行系統(tǒng)開發(fā)中贡珊,經(jīng)常會用到最爬,有點類似于OS中的批處理。對于一些實時性不高的任務(wù)门岔,比如退款爱致,消息推送,會用到定時任務(wù)寒随。)

首先需要使用的jar包:用maven在pom.xml中配置糠悯。版本有很多哦,自己可以去世界庫找一個牢裳。

 <dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>   
  • 方式一(相對代碼較多):通過XML文件配置逢防。通過上下文配置邏輯清晰。流程清晰蒲讯。通常情況下忘朝,我們的spring配置文件命名為applicationContext.xml,并且存放在resource文件夾下判帮。我們不妨在resource文件夾下新建一個spring文件夾局嘁。這個文件夾可以專門去配置一些spring集成框架。與spring是同級的晦墙。(為什么不配置到springMVC悦昵,問這個問題的同學(xué),可以去了解一下springMVC的原理晌畅。因為SpringMVC是一個servlet的框架但指,是作用于Web層,controller等等抗楔。而類似于quartz等框架是與SpringMVC平級的棋凳,是對定時任務(wù)進(jìn)行管理,作用于Conponent连躏,不屬于附屬關(guān)系剩岳。)然后新建一個XML文件 ,建議命名為:spring-scheduler.xml入热。

項目結(jié)構(gòu)圖如下

image.png

先上代碼拍棕。提前說一點晓铆,每一個class對應(yīng)的****FactoryBean是對應(yīng)的。一共有三個绰播, 要么都用***Bean骄噪,要么都用****FactoryBean。用混的情況下是會報錯的幅垮。(曾經(jīng)在eclipse沒報錯腰池,但是在idea報錯了)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <!-- 申明執(zhí)行任務(wù)的類 -->
    <bean id="messageSendJob" class="com.job.MessageSendJob"></bean>

    <!-- 申請線程池 -->
    <bean id="schedulerExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="10" />
        <property name="maxPoolSize" value="100" />
        <property name="queueCapacity" value="500" />
    </bean>

    <!-- 調(diào)度業(yè)務(wù) -->
    <bean id="messageSendJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="messageSendJob" />
        <property name="targetMethod" value="message" />
    </bean>

    <!-- 觸發(fā)器 -->
    <bean id="messageSendCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="messageSendJobDetail" />
        <property name="cronExpression" value="* 0/20 * * * ?" />
    </bean>

    <!-- 設(shè)置調(diào)度 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <ref bean="messageSendCronTrigger" />
            </list>
        </property>
        <property name="taskExecutor" ref="schedulerExecutor" />
    </bean>
</beans>
  • 該部分是spring-scheduler.xml配置文件的內(nèi)容。層級關(guān)系也十分明顯忙芒,配置內(nèi)容也很簡單。其中要介紹的就是cron表達(dá)式讳侨,可以自行百度呵萨。corn從左到右(用空格隔開):* * * * * ? * 通常情況下只使用六位,也就是 * * * * * ? 跨跨。最后一位用“?” , 下面有解釋

  • 秒 分 小時 月份中的日期 月份 星期中的日期 年份

  • 字段 允許值 允許的特殊字符

  • 秒(Seconds) 0~59的整數(shù) , - * / 四個字符

  • 分(Minutes) 0~59的整數(shù) , - * / 四個字符

  • 小時(Hours) 0~23的整數(shù) , - * / 四個字符

  • 日期(DayofMonth) 1~31的整數(shù)(但是你需要考慮你月的天數(shù)) ,- * ? / L W C 八個字符

  • 月份(Month) 1~12的整數(shù)或者 JAN-DEC , - * / 四個字符

  • 星期(DayofWeek) 1~7的整數(shù)或者 SUN-SAT (1=SUN) , - * ? / L C # 八個字符

  • 年(可選潮峦,留空)(Year) 1970~2099 , - * / 四個字符

  • (1)* :表示匹配該域的任意值。假如在Minutes域使用*, 即表示每分鐘都會觸發(fā)事件勇婴。

  • (2)? :只能用在DayofMonth和DayofWeek兩個域忱嘹。它也匹配域的任意值,但實際不會耕渴。因為- ####DayofMonth和DayofWeek會相互影響拘悦。例如想在每月的20日觸發(fā)調(diào)度,不管20日到底是星期幾橱脸,則只能使用如下寫法: 13 13 15 20 * ?, 其中最后一位只能用础米?,而不能使用添诉,如果使用表示不管星期幾都會觸發(fā)屁桑,實際上并不是這樣。

  • (3)- :表示范圍栏赴。例如在Minutes域使用5-20蘑斧,表示從5分到20分鐘每分鐘觸發(fā)一次

  • (4)/ :表示起始時間開始觸發(fā),然后每隔固定時間觸發(fā)一次须眷。例如在Minutes域使用5/20,則意味著5分鐘觸發(fā)一次竖瘾,而25,45等分別觸發(fā)一次.

  • (5), :表示列出枚舉值柒爸。例如:在Minutes域使用5,20准浴,則意味著在5和20分每分鐘觸發(fā)一次。

  • (6)L :表示最后捎稚,只能出現(xiàn)在DayofWeek和DayofMonth域乐横。如果在DayofWeek域使用5L,意味著在最后的一個星期四觸發(fā)求橄。

  • (7)W :表示有效工作日(周一到周五),只能出現(xiàn)在DayofMonth域,系統(tǒng)將在離指定日期的最近的有效工作日觸發(fā)事件葡公。例如:在 DayofMonth使用5W罐农,如果5日是星期六,則將在最近的工作日:星期五催什,即4日觸發(fā)涵亏。如果5日是星期天,則在6日(周一)觸發(fā)蒲凶;如果5日在星期一到星期五中的一天气筋,則就在5日觸發(fā)。另外一點旋圆,W的最近尋找不會跨過月份 宠默。

  • (8)LW :這兩個字符可以連用,表示在某個月最后一個工作日灵巧,即最后一個星期五搀矫。

  • (9)# :用于確定每個月第幾個星期幾,只能出現(xiàn)在DayofMonth域刻肄。例如在4#2瓤球,表示某月的第二個星期三。

其次一個需要介紹的就是具體的調(diào)度任務(wù)敏弃,也就是如下代碼塊

<!-- 調(diào)度業(yè)務(wù) -->
    <bean id="messageSendJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="messageSendJob" />
        <property name="targetMethod" value="message" />
    </bean>

bean的id自己命名卦羡,property中name自己命名。而ref中的調(diào)度業(yè)務(wù)权她。 我的調(diào)度業(yè)務(wù)如下

package com.job;

/**
 * @ author ezra
 * @ date 2019/2/18 15:56
 */

import com.service.MessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 消息推送定時任務(wù)
 * @author zjj
 * @date 2019-02-13
 */
@Component
public class MessageSendJob {

    private static final Logger logger = LoggerFactory.getLogger(MessageSendJob.class);

    /**
     * 每隔5分鐘查詢一次是否有消息
     */
    @Autowired
    private MessageService MessageService;

    public void message() {
        logger.info("【begin】執(zhí)行批量消息推送定時任務(wù)");
            // 執(zhí)行批量消息推送操作
            MessageService.messageAll();
        logger.info("【end】執(zhí)行批量消息推送定時任務(wù)");
    }


    /**
     * 每隔一星期設(shè)置無效form(暫時不實現(xiàn))
     */
/*
    public void templete() {
        logger.info("【begin】執(zhí)行批量formid失效刪除定時任務(wù)");
        // 為了防止定時任務(wù)多線程并行執(zhí)行時出現(xiàn)退款多次的情況虹茶,對過程加上互斥鎖保證該任務(wù)串行執(zhí)行
        // 如果后期應(yīng)用改為多機(jī)部署,需要將此處改為分布式鎖或者由分布式任務(wù)調(diào)度系統(tǒng)協(xié)調(diào)串行執(zhí)行
        synchronized (OrderRefundJob.class) {
            // 執(zhí)行批量退款操作
            MessageService.templateDelete();
        }
        logger.info("【end】執(zhí)行批量formid失效刪除定時任務(wù)");
    }
*/
}

完成以上操作之后隅要,基本上定時任務(wù)已經(jīng)配置完成蝴罪。接下來最后一步,是通過web.xml去加載步清,應(yīng)該每個人都知道applicationContext.xml的加載吧要门,在后面添加classpath:spring/spring-scheduler.xml即可。

  <!-- 獲取requst respose對象-->
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    <!-- 利用Spring提供的ContextLoaderListener監(jiān)聽器去監(jiān)聽ServletContext對象的創(chuàng)建廓啊,并初始化WebApplicationContext對象 -->
   <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>
   <!-- Context Configuration locations for Spring XML files(默認(rèn)查找/WEB-INF/applicationContext.xml) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml欢搜,classpath:spring/spring-scheduler.xml</param-value>
    </context-param>

方法二,非常暴力谴轮,在application里面掃描添加掃描項<task:annotation-driven/>

通過注解完成炒瘟。@Scheduled 后面接cron表達(dá)式。相當(dāng)于集成spring-task

@Component
public class OrderRefundJob {

    private static final Logger logger = LoggerFactory.getLogger(OrderRefundJob.class);

    @Autowired
    private RefundService RefundService;


    @Scheduled(cron = "* 0/5 *  * * ?")
    public void refund() {
        logger.info("【begin】執(zhí)行批量退款定時任務(wù)開始");
        // 執(zhí)行批量退款操作
        RefundService.refundAll();
        logger.info("【end】執(zhí)行批量退款定時任務(wù)結(jié)束");
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末第步,一起剝皮案震驚了整個濱河市缘琅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廓推,老刑警劉巖刷袍,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異樊展,居然都是意外死亡呻纹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門专缠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雷酪,“玉大人,你說我怎么就攤上這事藤肢√耄” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵嘁圈,是天一觀的道長。 經(jīng)常有香客問我蟀淮,道長最住,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任怠惶,我火速辦了婚禮涨缚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘策治。我一直安慰自己脓魏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布通惫。 她就那樣靜靜地躺著茂翔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪履腋。 梳的紋絲不亂的頭發(fā)上珊燎,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音遵湖,去河邊找鬼悔政。 笑死,一個胖子當(dāng)著我的面吹牛延旧,可吹牛的內(nèi)容都是我干的谋国。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼迁沫,長吁一口氣:“原來是場噩夢啊……” “哼芦瘾!你這毒婦竟也來了捌蚊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤旅急,失蹤者是張志新(化名)和其女友劉穎逢勾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藐吮,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡溺拱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谣辞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迫摔。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泥从,靈堂內(nèi)的尸體忽然破棺而出句占,到底是詐尸還是另有隱情,我是刑警寧澤躯嫉,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布纱烘,位于F島的核電站,受9級特大地震影響祈餐,放射性物質(zhì)發(fā)生泄漏擂啥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一帆阳、第九天 我趴在偏房一處隱蔽的房頂上張望哺壶。 院中可真熱鬧,春花似錦蜒谤、人聲如沸山宾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽资锰。三九已至,卻和暖如春旬盯,著一層夾襖步出監(jiān)牢的瞬間台妆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工胖翰, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留接剩,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓萨咳,卻偏偏與公主長得像懊缺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345