javascript
与Spring的计划任务一起按时运行
您是否需要每天像鬧鐘一樣在同一時(shí)間運(yùn)行某個(gè)流程? 然后,Spring的預(yù)定任務(wù)適合您。 允許您使用@Scheduled注釋方法,以使其在指定的時(shí)間或內(nèi)部間隔運(yùn)行。 在本文中,我們將研究如何設(shè)置一個(gè)可以使用計(jì)劃任務(wù)的項(xiàng)目,以及如何使用不同的方法來定義它們的執(zhí)行時(shí)間。
我將在本文中使用Spring Boot,以使依賴關(guān)系變得簡潔而又簡單,這是因?yàn)榭梢詫pring-boot-starter依賴項(xiàng)進(jìn)行調(diào)度,該依賴項(xiàng)將以某種方式包含在幾乎每個(gè)Spring Boot項(xiàng)目中。 這使您可以使用任何其他啟動程序依賴項(xiàng),因?yàn)樗鼈儠雜pring-boot-starter及其所有關(guān)系。 如果要包括確切的依賴項(xià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ù)非常簡單。 將@Scheduled批注添加到希望自動運(yùn)行的任何方法中,并將@EnableScheduling包含在配置文件中。
因此,例如,您可能會遇到類似以下的內(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!");} }這里有很多代碼對于運(yùn)行計(jì)劃任務(wù)并不重要。 正如我在一分鐘前說過的,我們需要在方法上使用@Scheduled ,它將自動開始運(yùn)行。 因此,在上面的示例中, create方法將每隔1000毫秒(1秒)開始運(yùn)行,如注釋的fixedRate屬性所示。 如果我們想更改其運(yùn)行頻率,則可以增加或減少fixedRate時(shí)間,或者可以考慮使用可用的不同調(diào)度方法。
因此,您可能想知道這些其他方法是正確的嗎? 好了,它們就在這里(我還將在此處包括fixedRate )。
- fixedRate在fixedRate調(diào)用之間以固定的毫秒周期執(zhí)行該方法。
 - fixedRateString一樣的fixedRate ,但有一個(gè)字符串值來代替。
 - fixedDelay在一次調(diào)用結(jié)束與下一次調(diào)用之間以固定的毫秒周期執(zhí)行該方法。
 - fixedDelayString一樣fixedDelay但一個(gè)字符串值來代替。
 - cron使用類似cron的表達(dá)式來確定何時(shí)執(zhí)行該方法(我們將在以后更深入地介紹此方法)。
 
@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è)字符串值來代替。
 
以下是一些使用固定速率和延遲的示例。
@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)在來看一下cron屬性,它可以對任務(wù)的計(jì)劃進(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或特殊字符, - * / 。
 
為了更加清楚起見,我將細(xì)目分類組合成一個(gè)由字段標(biāo)簽組成的表達(dá)式。
@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")請不要在表達(dá)式中包括花括號(我使用它們使表達(dá)式更清晰)。
在繼續(xù)之前,我們需要了解特殊字符的含義。
- *表示所有值,因此,如果在第二個(gè)字段中使用,則表示每秒或在天字段中使用,表示每天運(yùn)行。
 - ? 表示沒有特定的值,并且可以在“月的天”或“星期幾”字段中使用,其中使用一個(gè)會使另一個(gè)無效。 如果我們指定在一個(gè)月的15日觸發(fā),則一個(gè)? 將在“ Day of week字段中使用。
 - -表示值的范圍(例如,小時(shí)數(shù)字段中的1-3表示小時(shí)數(shù)1、2和3)。
 - ,代表附加價(jià)值,例如周一,周三,SUN在本周,說明此一天,在周一,周三和周日。
 - /代表增量,例如,秒字段中的0/15從0(0、15、30和45)開始每15秒觸發(fā)一次。
 - L代表一周或一個(gè)月的最后一天。 請記住,在這種情況下,星期六是一周的結(jié)束,因此在“星期幾”字段中使用L將在星期六觸發(fā)。 可以將其與月日字段中的數(shù)字結(jié)合使用,例如6L代表月的最后一個(gè)星期五,或者L-3這樣的表達(dá)式表示月的最后一天。 如果我們在星期幾字段中指定一個(gè)值,則必須使用? 在“月”字段中,反之亦然。
 - W表示每月的最接近的工作日。 例如,如果15W是工作日,則在每月的第15天觸發(fā),否則它將在最近的工作日運(yùn)行。 該值不能在日期值列表中使用。
 - #指定任務(wù)應(yīng)該在星期幾和星期幾觸發(fā)。 例如, 5#2表示該月的第二個(gè)星期四。 如果您指定的日期和星期溢出到下個(gè)月,則不會觸發(fā)。
 
在這里可以找到有用的資源,其中的解釋稍長一些,這有助于我撰寫本文。
讓我們來看幾個(gè)例子。
@Scheduled(cron = "0 0 12 * * ?")每天晚上12點(diǎn)開火。
@Scheduled(cron = "0 15 10 * * ? 2005")2005年每天早上10:15觸發(fā)。
@Scheduled(cron = "0/20 * * * * ?")每20秒觸發(fā)一次。
有關(guān)更多示例,請參閱我前面提到的鏈接, 此處再次顯示。 幸運(yùn)的是,如果您在編寫一個(gè)簡單的cron表達(dá)式時(shí)遇到麻煩,那么您應(yīng)該可以在Google中找到所需的方案,因?yàn)橛腥丝赡芤呀?jīng)在Stack Overflow上問了同樣的問題。
要將上述內(nèi)容與一個(gè)小的代碼示例綁定在一起,請參見下面的代碼。
@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è)類,每20秒向Cassandra查詢一次同一時(shí)間段內(nèi)事件的平均值。 同樣,這里的大多數(shù)代碼都是@Scheduled批注中的噪音,但在野外看到它可能會有所幫助。 此外,如果您觀察到這一情況,則對于每20秒運(yùn)行一次的用例,在此處使用頻繁運(yùn)行任務(wù)的情況下,使用fixedRate以及可能使用fixedDelay屬性而不是cron更為合適。
@Scheduled(fixedRate = 20000)是上面使用的cron表達(dá)式的fixedRate等效項(xiàng)。
我前面提到的最終要求是將@EnableScheduling批注添加到配置類。
@SpringBootApplication @EnableScheduling public class Application {public static void main(final String args[]) {SpringApplication.run(Application.class);} }作為一個(gè)很小的Spring Boot應(yīng)用程序,我已將@EnableScheduling批注附加到主@SpringBootApplication類。
總而言之,我們可以安排任務(wù)使用@Scheduled注釋以及執(zhí)行之間的毫秒級速率或cron表達(dá)式來觸發(fā),以實(shí)現(xiàn)無法用前者表達(dá)的更佳時(shí)序。 對于需要非常頻繁運(yùn)行的任務(wù),使用fixedRate或fixedDelay屬性就足夠了,但是一旦執(zhí)行之間的時(shí)間變大,則很難快速確定所定義的時(shí)間。 發(fā)生這種情況時(shí),應(yīng)使用cron屬性以更好地了解計(jì)劃的時(shí)間。
這篇文章中使用的少量代碼可以在我的GitHub上找到 。
如果您發(fā)現(xiàn)這篇文章很有幫助,并希望在我撰寫新教程時(shí)保持最新,請?jiān)赥witter上@LankyDanDev關(guān)注我。
翻譯自: https://www.javacodegeeks.com/2018/02/running-time-springs-scheduled-tasks.html
總結(jié)
以上是生活随笔為你收集整理的与Spring的计划任务一起按时运行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 三星bada系统手机(三星bada系统手
 - 下一篇: 80手机电影网 80s手机电影网站下载的