【轉(zhuǎn)】解析 Spring 計劃任務執(zhí)行多次之謎及解決方案


description: "在 Spring 項目中响牛,@Scheduled 注解配置的計劃任務(Scheduled Tasks)可能會出現(xiàn)執(zhí)行多次的情況"
date: 2024.11.03 10:34
categories:
- Spring
tags: [Spring]
keywords: Spring, @Scheduled, extends, 重復執(zhí)行


原文地址:https://wyiyi.github.io/amber/2024/11/01/Scheduled/

Spring項目中饶米,@Scheduled注解配置的計劃任務(Scheduled Tasks)可能會出現(xiàn)執(zhí)行多次的情況轨功,尤其是在以下場景中:

  • 一個父類定義了@Scheduled注解的方法岔冀,且被多個子類繼承。
  • 父類或子類被Spring容器錯誤地實例化為多個Bean實例。

本文將針對該特定場景,剖析導致計劃任務重復執(zhí)行的原因蛤奥,并針對性地提出解決措施。

一僚稿、現(xiàn)象描述

Spring項目中凡桥,我們定義了一個計劃任務類ScheduledTaskParent,以及兩個繼承該類的子類FirstChildSecondChild蚀同。

@Component
public class ScheduledTaskParent {

    @Scheduled(fixedRate = 5000)
    public void performTask() {
        System.out.println("ScheduledTaskParent 執(zhí)行計劃任務");
    }
}

@Component
public class FirstChild extends ScheduledTaskParent {

    @Scheduled(fixedRate = 5000)
    public void firstTask() {
        System.out.println("FirstChild 執(zhí)行特定的操作");
    }
}

@Component
public class SecondChild extends ScheduledTaskParent {

    @Scheduled(fixedRate = 5000)
    public void secondTak() {
        System.out.println("SecondChild 執(zhí)行計劃任務");
    }
}

當應用啟動后缅刽,發(fā)現(xiàn)ScheduledTaskParent中的計劃任務被執(zhí)行了多次,具體表現(xiàn)為每個子類實例都執(zhí)行了父類的計劃任務蠢络,導致執(zhí)行次數(shù)為子類數(shù)目加1衰猛。

FirstChild 執(zhí)行特定的操作
ScheduledTaskParent 執(zhí)行計劃任務
ScheduledTaskParent 執(zhí)行計劃任務
SecondChild 執(zhí)行計劃任務
ScheduledTaskParent 執(zhí)行計劃任務

二、原因分析

As of Spring Framework 4.3, @Scheduled methods are supported on beans of any scope.

Make sure that you are not initializing multiple instances of the same @Scheduled annotation class at runtime, unless you do want to schedule callbacks to each such instance. Related to this, make sure that you do not use @Configurable on bean classes that are annotated with @Scheduled and registered as regular Spring beans with the container. Otherwise, you would get double initialization (once through the container and once through the @Configurable aspect), with the consequence of each @Scheduled method being invoked twice.

Spring 官方文檔 提到刹孔,從Spring Framework 4.3開始啡省,@Scheduled注解支持任何作用域的bean。但是髓霞,文檔也警告卦睹,不應該在運行時初始化同一@Scheduled注解類的多個實例,除非希望每個實例都調(diào)度回調(diào)方库。

在例子中结序,ScheduledTaskParent被標記為@Component,因此Spring容器會為其創(chuàng)建一個bean纵潦。由于FirstChildSecondChild都繼承了ScheduledTaskParent徐鹤,并且它們也被標記為@ComponentSpring容器為每個子類也創(chuàng)建了bean邀层。每個bean都包含performTask方法上的@Scheduled注解返敬,因此每個bean都會觸發(fā)該任務的調(diào)度。

這就是為什么performTask被執(zhí)行了三次:
一次來自ScheduledTaskParentbean被济,一次來自FirstChildbean救赐,還有一次來自SecondChildbean

三、解決方案

為了防止計劃任務在子類中被重復執(zhí)行经磅,我們可以在父類中定義一個抽象方法泌绣,并在子類中實現(xiàn)具體的計劃任務。如下所示:

public abstract class ScheduledTaskParent {

    public abstract void performTask();
}

@Component
public class FirstChild extends ScheduledTaskParent {

    @Scheduled(fixedRate = 5000)
    @Override
    public void performTask() {
        System.out.println("FirstChild 執(zhí)行特定的操作");
    }
}

@Component
public class SecondChild extends ScheduledTaskParent {

    @Scheduled(fixedRate = 5000)
    @Override
    public void performTask() {
        System.out.println("SecondChild 執(zhí)行計劃任務");
    }
}

通過這種方式预厌,確保每個計劃任務只被調(diào)度一次阿迈,即使有多個子類繼承了父類。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轧叽,一起剝皮案震驚了整個濱河市苗沧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炭晒,老刑警劉巖待逞,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異网严,居然都是意外死亡识樱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門震束,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怜庸,“玉大人,你說我怎么就攤上這事垢村「罴玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵嘉栓,是天一觀的道長宏榕。 經(jīng)常有香客問我,道長侵佃,這世上最難降的妖魔是什么担扑? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮趣钱,結果婚禮上,老公的妹妹穿的比我還像新娘胚宦。我一直安慰自己首有,他們只是感情好,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布枢劝。 她就那樣靜靜地躺著井联,像睡著了一般。 火紅的嫁衣襯著肌膚如雪您旁。 梳的紋絲不亂的頭發(fā)上烙常,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼蚕脏。 笑死侦副,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的驼鞭。 我是一名探鬼主播秦驯,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挣棕!你這毒婦竟也來了译隘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤洛心,失蹤者是張志新(化名)和其女友劉穎固耘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體词身,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡厅目,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了偿枕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片璧瞬。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖渐夸,靈堂內(nèi)的尸體忽然破棺而出嗤锉,到底是詐尸還是另有隱情,我是刑警寧澤墓塌,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布瘟忱,位于F島的核電站,受9級特大地震影響苫幢,放射性物質(zhì)發(fā)生泄漏访诱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一韩肝、第九天 我趴在偏房一處隱蔽的房頂上張望触菜。 院中可真熱鬧,春花似錦哀峻、人聲如沸涡相。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽催蝗。三九已至,卻和暖如春育特,著一層夾襖步出監(jiān)牢的瞬間丙号,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留犬缨,地道東北人喳魏。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像遍尺,于是被迫代替她去往敵國和親截酷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容