javascript
spring 计划任务_与Spring的计划任务一起按时运行
spring 計(jì)劃任務(wù)
您是否需要每天像鬧鐘一樣在同一時(shí)間運(yùn)行某個(gè)流程? 然后,Spring的預(yù)定任務(wù)適合您。 允許您使用@Scheduled注釋方法,以使其在指定的時(shí)間或內(nèi)部間隔運(yùn)行。 在本文中,我們將研究建立一個(gè)可以使用計(jì)劃任務(wù)的項(xiàng)目,以及如何使用不同的方法來(lái)定義它們的執(zhí)行時(shí)間。
我將在本文中使用Spring Boot,以使依賴(lài)關(guān)系變得簡(jiǎn)潔而又簡(jiǎn)單,這是因?yàn)檎{(diào)度可用于spring-boot-starter依賴(lài)關(guān)系,該依賴(lài)關(guān)系幾乎以某種方式包含在每個(gè)Spring Boot項(xiàng)目中。 這使您可以使用任何其他啟動(dòng)程序依賴(lài)項(xiàng),因?yàn)樗鼈儠?huì)引入spring-boot-starter及其所有關(guān)系。 如果要包括確切的依賴(lài)項(xiàng)本身,請(qǐng)使用spring-context 。
您可以使用spring-boot-starter 。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.0.0.RC1</version> </dependency>或直接使用spring-context 。
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.3.RELEASE</version> </dependency>創(chuàng)建計(jì)劃任務(wù)非常簡(jiǎn)單。 將@Scheduled批注添加到希望自動(dòng)運(yùn)行的任何方法中,并將@EnableScheduling包含在配置文件中。
因此,例如,您可能會(huì)遇到類(lèi)似以下的內(nèi)容。
@Component public class EventCreator {private static final Logger LOG = LoggerFactory.getLogger(EventCreator.class);private final EventRepository eventRepository;public EventCreator(final EventRepository eventRepository) {this.eventRepository = eventRepository;}@Scheduled(fixedRate = 1000)public void create() {final LocalDateTime start = LocalDateTime.now();eventRepository.save(new Event(new EventKey("An event type", start, UUID.randomUUID()), Math.random() * 1000));LOG.debug("Event created!");} }這里有很多代碼對(duì)于運(yùn)行計(jì)劃任務(wù)并不重要。 正如我在一分鐘前說(shuō)過(guò)的,我們需要在方法上使用@Scheduled ,它將自動(dòng)開(kāi)始運(yùn)行。 因此,在上面的示例中, create方法將每隔1000毫秒(1秒)開(kāi)始運(yùn)行,如注釋的fixedRate屬性所示。 如果我們想更改其運(yùn)行頻率,則可以增加或減少fixedRate時(shí)間,或者可以考慮使用可用的不同調(diào)度方法。
因此,您可能想知道其他方法是正確的嗎? 好了,它們就在這里(我還將在此處包括fixedRate )。
- fixedRate在fixedRate調(diào)用之間以固定的毫秒周期執(zhí)行該方法。
- fixedRateString一樣的fixedRate ,但有一個(gè)字符串值來(lái)代替。
- fixedDelay在一次調(diào)用結(jié)束與下一次調(diào)用之間以固定的毫秒fixedDelay執(zhí)行該方法。
- fixedDelayString一樣fixedDelay但一個(gè)字符串值來(lái)代替。
- cron使用類(lèi)似cron的表達(dá)式來(lái)確定何時(shí)執(zhí)行該方法(我們將在稍后對(duì)此進(jìn)行更深入的研究)。
@Scheduled批注還有一些其他實(shí)用程序?qū)傩浴?
- zone指示將解析cron表達(dá)式的時(shí)區(qū),如果不包括時(shí)區(qū),它將使用服務(wù)器的默認(rèn)時(shí)區(qū)。 因此,如果您需要它在特定時(shí)區(qū)運(yùn)行,例如香港,則可以使用zone = "GMT+8:00" 。
- initialDelay延遲第一次執(zhí)行計(jì)劃任務(wù)的毫秒數(shù),需要使用固定速率或固定延遲屬性之一。
- initialDelayString同為initialDelay但一個(gè)字符串值來(lái)代替。
以下是一些使用固定速率和延遲的示例。
@Scheduled(fixedRate = 1000)與之前相同,每1秒運(yùn)行一次。
@Scheduled(fixedRateString = "1000")同上。
@Scheduled(fixedDelay = 1000)在上一次調(diào)用完成后運(yùn)行1秒。
@Scheduled(fixedRate = 1000, initialDelay = 5000)每秒運(yùn)行一次,但要等待5秒鐘才能首次執(zhí)行。
現(xiàn)在來(lái)看一下cron屬性,它可以對(duì)任務(wù)的調(diào)度進(jìn)行更多控制,讓我們定義任務(wù)運(yùn)行的秒數(shù),分鐘數(shù)和小時(shí)數(shù),還可以進(jìn)一步定義任務(wù)的運(yùn)行年限。
以下是構(gòu)建cron表達(dá)式的組件的細(xì)分。
- Seconds值可以為0-59或特殊字符, - * / 。
- Minutes值可以為0-59或特殊字符, - * / 。
- Hours值可以為0-59或特殊字符, - * / 。
- Day of month值可以為1-31或特殊字符, - * ? / LWC , - * ? / LWC 。
- Month值可以為1-12 , JAN-DEC或特殊字符, - * / 。
- Day of week值可以是1-7 , SUN-SAT或特殊字符, - * ? / LC # , - * ? / LC # 。
- Year可以為空,值可以為1970-2099或特殊字符, - * / 。
為了更加清晰起見(jiàn),我將細(xì)目分類(lèi)組合成一個(gè)由字段標(biāo)簽組成的表達(dá)式。
@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")請(qǐng)不要在表達(dá)式中包括花括號(hào)(我用它們來(lái)使表達(dá)式更清晰)。
在我們繼續(xù)之前,我們需要了解特殊字符的含義。
- *表示所有值,因此,如果在第二個(gè)字段中使用,則表示每秒或在天字段中使用,表示每天運(yùn)行。
- ? 表示沒(méi)有特定的值,并且可以在“月的天”或“星期幾”字段中使用,其中使用一個(gè)會(huì)使另一個(gè)無(wú)效。 如果我們指定在一個(gè)月的15日觸發(fā),則一個(gè)? 將在“ Day of week字段中使用。
- -表示值的范圍(例如,小時(shí)數(shù)字段中的1-3表示小時(shí)數(shù)1、2和3)。
- ,代表附加價(jià)值,例如周一,周三,SUN在本周,說(shuō)明此一天,在周一,周三和周日。
- /代表增量,例如,秒字段中的0/15從0(0、15、30和45)開(kāi)始每15秒觸發(fā)一次。
- L代表一周或一個(gè)月的最后一天。 請(qǐng)記住,在這種情況下,星期六是一周的結(jié)束,因此在星期幾字段中使用L將在星期六觸發(fā)。 可以與月日字段中的數(shù)字結(jié)合使用,例如6L代表月的最后一個(gè)星期五,或者L-3這樣的表達(dá)式表示月的最后一天。 如果我們?cè)凇靶瞧趲住弊侄沃兄付ㄒ粋€(gè)值,則必須使用? 在“日”字段中,反之亦然。
- W表示每月的最接近的工作日。 例如,如果15W是工作日,則在每月的第15天觸發(fā),否則它將在最近的工作日運(yùn)行。 該值不能用于日期值列表中。
- #指定任務(wù)應(yīng)該在星期幾和星期幾觸發(fā)。 例如, 5#2表示該月的第二個(gè)星期四。 如果您指定的日期和星期溢出到下個(gè)月,則不會(huì)觸發(fā)。
在這里可以找到有用的資源,其中的解釋稍長(zhǎng)一些,這有助于我撰寫(xiě)本文。
讓我們來(lái)看幾個(gè)例子。
@Scheduled(cron = "0 0 12 * * ?")每天晚上12點(diǎn)開(kāi)火。
@Scheduled(cron = "0 15 10 * * ? 2005")2005年每天早上10:15觸發(fā)。
@Scheduled(cron = "0/20 * * * * ?")每20秒觸發(fā)一次。
有關(guān)更多示例,請(qǐng)參見(jiàn)我前面提到的鏈接, 此處再次顯示。 幸運(yùn)的是,如果您在編寫(xiě)一個(gè)簡(jiǎn)單的cron表達(dá)式時(shí)遇到麻煩,那么您應(yīng)該可以在Google中找到所需的方案,因?yàn)橛腥丝赡芤呀?jīng)在Stack Overflow上問(wèn)了相同的問(wèn)題。
要將上述內(nèi)容與一個(gè)小的代碼示例綁定在一起,請(qǐng)參見(jiàn)下面的代碼。
@Component public class AverageMonitor {private static final Logger LOG = LoggerFactory.getLogger(AverageMonitor.class);private final EventRepository eventRepository;private final AverageRepository averageRepository;public AverageMonitor(final EventRepository eventRepository, final AverageRepository averageRepository) {this.eventRepository = eventRepository;this.averageRepository = averageRepository;}@Scheduled(cron = "0/20 * * * * ?")public void publish() {final double average =eventRepository.getAverageValueGreaterThanStartTime("An event type", LocalDateTime.now().minusSeconds(20));averageRepository.save(new Average(new AverageKey("An event type", LocalDateTime.now()), average));LOG.info("Average value is {}", average);} }在這里,我們有一個(gè)類(lèi),每20秒查詢(xún)Cassandra以獲取同一時(shí)間段內(nèi)事件的平均值。 同樣,這里的大多數(shù)代碼都是@Scheduled批注中的噪音,但是在野外看到它可能會(huì)有所幫助。 此外,如果您一直保持觀察,對(duì)于這種每20秒運(yùn)行一次的用例,在這里我們使用頻率如此之高,因此,使用fixedRate以及可能使用fixedDelay屬性代替cron更為合適。
@Scheduled(fixedRate = 20000)是上面使用的cron表達(dá)式的fixedRate等效項(xiàng)。
我前面提到的最終要求是將@EnableScheduling批注添加到配置類(lèi)。
@SpringBootApplication @EnableScheduling public class Application {public static void main(final String args[]) {SpringApplication.run(Application.class);} }作為一個(gè)很小的Spring Boot應(yīng)用程序,我已經(jīng)將@EnableScheduling批注附加到主@SpringBootApplication類(lèi)。
總而言之,我們可以安排任務(wù)使用@Scheduled注釋以及執(zhí)行之間的毫秒級(jí)速率或cron表達(dá)式來(lái)觸發(fā),以實(shí)現(xiàn)無(wú)法用前者表達(dá)的更精確的時(shí)序。 對(duì)于需要經(jīng)常運(yùn)行的任務(wù),使用fixedRate或fixedDelay屬性就足夠了,但是一旦執(zhí)行之間的時(shí)間變大,則很難快速確定所定義的時(shí)間。 發(fā)生這種情況時(shí),應(yīng)使用cron屬性以更好地了解計(jì)劃的時(shí)間。
這篇文章中使用的少量代碼可以在我的GitHub上找到 。
如果您發(fā)現(xiàn)這篇文章很有幫助,并希望在我撰寫(xiě)新教程時(shí)保持最新,請(qǐng)?jiān)赥witter上@LankyDanDev關(guān)注我。
翻譯自: https://www.javacodegeeks.com/2018/02/running-time-springs-scheduled-tasks.html
spring 計(jì)劃任務(wù)
總結(jié)
以上是生活随笔為你收集整理的spring 计划任务_与Spring的计划任务一起按时运行的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 化学专业尽早转行_尽早查看针对Java
- 下一篇: php cdi_CDI中的事务异常处理