第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Spring Boot 定時(shí)任務(wù)

1. 前言

定時(shí)任務(wù)絕對(duì)是實(shí)際項(xiàng)目中的剛需。

  • 我們想監(jiān)控一個(gè)重點(diǎn)服務(wù)的運(yùn)行狀態(tài),可以每隔 1 分鐘調(diào)用下該服務(wù)的心跳接口,調(diào)用失敗時(shí)即發(fā)出告警信息;
  • 我們想每天凌晨的時(shí)候,將所有商品的庫存置滿,以免早上忘記添加庫存影響銷售;
  • 我們想在每個(gè)周六的某個(gè)時(shí)段進(jìn)行打折促銷。

在以上的案例中,或者是指定時(shí)間間隔,或者是指定時(shí)間節(jié)點(diǎn),按設(shè)定的任務(wù)進(jìn)行某種操作,這就是定時(shí)任務(wù)了。

在 Spring Boot 中實(shí)現(xiàn)定時(shí)任務(wù)簡單而靈活,本節(jié)我們來體驗(yàn)下。

2. Spring Task 定時(shí)任務(wù)

Spring Task 是 Spring Boot 內(nèi)置的定時(shí)任務(wù)模塊,可以滿足大部分的定時(shí)任務(wù)場景需求。

通過為方法添加一個(gè)簡單的注解,即可按設(shè)定的規(guī)則定時(shí)執(zhí)行該方法。

下面就演示下 Spring Boot 中使用 Spring Task 的具體方法。

2.1 使用 Spring Initializr 創(chuàng)建項(xiàng)目

Spring Boot 版本選擇 2.2.5 ,Group 為 com.imooc , Artifact 為 spring-boot-task ,生成項(xiàng)目后導(dǎo)入 Eclipse 開發(fā)環(huán)境。

2.2 開啟定時(shí)任務(wù)

在啟動(dòng)類上添加 @EnableScheduling 注解,開啟定時(shí)任務(wù)功能。

實(shí)例:

@SpringBootApplication
@EnableScheduling // 開啟定時(shí)任務(wù)
public class SpringBootTaskApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringBootTaskApplication.class, args);
	}
}

2.3 通過注解設(shè)定定時(shí)任務(wù)

新建 MySpringTask 任務(wù)類,添加 @Component 注解注冊(cè) Spring 組件,定時(shí)任務(wù)方法需要在 Spring 組件類才能生效。

注意類中方法添加了 @Scheduled 注解,所以會(huì)按照 @Scheduled 注解參數(shù)指定的規(guī)則定時(shí)執(zhí)行。

實(shí)例:

/**
 * 任務(wù)類
 */
@Component
public class MySpringTask {
	/**
	 * 每2秒執(zhí)行1次
	 */
	@Scheduled(fixedRate = 2000)
	public void fixedRateMethod() throws InterruptedException {
		System.out.println("fixedRateMethod:" + new Date());
		Thread.sleep(1000);
	}
}

上面例子執(zhí)行情況如下,可見是每隔 2 秒執(zhí)行 1 次。

fixedRateMethod:Fri May 15 22:04:52 CST 2020
fixedRateMethod:Fri May 15 22:04:54 CST 2020
fixedRateMethod:Fri May 15 22:04:56 CST 2020

實(shí)例:

/**
 * 任務(wù)類
 */
@Component
public class MySpringTask {
	/**
	 * 執(zhí)行結(jié)束2秒后執(zhí)行下次任務(wù)
	 */
	@Scheduled(fixedDelay = 2000)
	public void fixedDelayMethod() throws InterruptedException {
		System.out.println("fixedDelayMethod:" + new Date());
		Thread.sleep(1000);
	}
}

上面的例子執(zhí)行情況如下,每次打印后先等待 1 秒,然后方法執(zhí)行結(jié)束 2 秒后再次執(zhí)行任務(wù),所以是每 3 秒打印 1 行內(nèi)容。

fixedDelayMethod:Fri May 15 22:08:26 CST 2020
fixedDelayMethod:Fri May 15 22:08:29 CST 2020
fixedDelayMethod:Fri May 15 22:08:32 CST 2020

2.4 使用 Cron 表達(dá)式

@Scheduled 也支持使用 Cron 表達(dá)式, Cron 表達(dá)式可以非常靈活地設(shè)置定時(shí)任務(wù)的執(zhí)行時(shí)間。以本節(jié)開頭的兩個(gè)需求為例:

  • 我們想監(jiān)控一個(gè)重點(diǎn)服務(wù)的運(yùn)行狀態(tài),可以每隔 1 分鐘調(diào)用下該服務(wù)的心跳接口,調(diào)用失敗時(shí)即發(fā)出告警信息;
  • 我們想在每天凌晨的時(shí)候,將所有商品的庫存置滿,以免早上忘記添加庫存影響銷售。

對(duì)應(yīng)的定時(shí)任務(wù)實(shí)現(xiàn)如下:

實(shí)例:

/**
 * 任務(wù)類
 */
@Component
public class MySpringTask {
	/**
	 * 在每分鐘的00秒執(zhí)行
	 */
	@Scheduled(cron = "0 * * * * ?")
	public void jump() throws InterruptedException {
		System.out.println("心跳檢測:" + new Date());
	}
	/**
	 * 在每天的00:00:00執(zhí)行
	 */
	@Scheduled(cron = "0 0 0 * * ?")
	public void stock() throws InterruptedException {
		System.out.println("置滿庫存:" + new Date());
	}
}

Cron 表達(dá)式并不難理解,從左到右一共 6 個(gè)位置,分別代表秒、時(shí)、分、日、月、星期,以秒為例:

  • 如果該位置上是 0 ,表示在第 0 秒執(zhí)行;
  • 如果該位置上是 * ,表示每秒都會(huì)執(zhí)行;
  • 如果該位置上是 ? ,表示該位置的取值不影響定時(shí)任務(wù),由于月份中的日和星期可能會(huì)發(fā)生意義沖突,所以日、 星期中需要有一個(gè)配置為 ?

按照上面的理解,cron = "0 * * * * ?" 表示在每分鐘的 00 秒執(zhí)行、cron = "0 0 0 * * ?" 表示在每天的 00:00:00 執(zhí)行。

Tips:Cron 表達(dá)式的描述能力很強(qiáng),此處只是簡單提及,感興趣的同學(xué)可以自行查閱相關(guān)資料了解更多信息。

3. Quartz 定時(shí)任務(wù)

Spring Task 已經(jīng)可以滿足絕大多數(shù)項(xiàng)目對(duì)定時(shí)任務(wù)的需求,但是在企業(yè)級(jí)應(yīng)用這個(gè)領(lǐng)域,還有更加強(qiáng)大靈活的 Quartz 框架可供選擇。

圖片描述

Quartz 官網(wǎng)介紹:企業(yè)級(jí)的任務(wù)調(diào)度框架

舉個(gè)例子,當(dāng)我們想根據(jù)數(shù)據(jù)庫中的配置,動(dòng)態(tài)地指定商品打折的時(shí)間區(qū)間時(shí),就可以利用 Quartz 框架來實(shí)現(xiàn)。 OK ,接下來我們就來具體完整實(shí)現(xiàn)下。

3.1 使用 Spring Initializr 創(chuàng)建項(xiàng)目

Spring Boot 版本選擇 2.2.5 ,Group 為 com.imooc , Artifact 為 spring-boot-quartz ,生成項(xiàng)目后導(dǎo)入 Eclipse 開發(fā)環(huán)境。

3.2 引入項(xiàng)目依賴

需要引入 Quartz 框架相關(guān)依賴。

實(shí)例:

		<!-- Quartz -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-quartz</artifactId>
		</dependency>

3.3 開啟定時(shí)任務(wù)

同樣需要,在啟動(dòng)類上添加 @EnableScheduling 注解,開啟定時(shí)任務(wù)功能。

實(shí)例:

@SpringBootApplication
@EnableScheduling // 開啟定時(shí)任務(wù)
public class SpringBootQuartzApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringBootQuartzApplication.class, args);
	}
}

3.4 Quartz 定時(shí)任務(wù)開發(fā)

Quartz 定時(shí)任務(wù)需要通過 Job 、 Trigger 、 JobDetail 來設(shè)置。

  • Job:具體任務(wù)操作類
  • Trigger:觸發(fā)器,設(shè)定執(zhí)行任務(wù)的時(shí)間
  • JobDetail:指定觸發(fā)器執(zhí)行的具體任務(wù)類及方法

我們先開發(fā)一個(gè) Job 組件:

實(shí)例:

/**
 * 打折任務(wù)
 */
@Component // 注冊(cè)到容器中
public class DiscountJob {
	/**
	 * 執(zhí)行打折
	 */
	public void execute() {
		System.out.println("更新數(shù)據(jù)庫中商品價(jià)格,統(tǒng)一打5折");
	}
}

然后在配置類中設(shè)定 Trigger 及 JobDetail 。

實(shí)例:

/**
 * 定時(shí)任務(wù)配置
 */
@Configuration
public class QuartzConfig {
	/**
	 * 配置JobDetail工廠組件,生成的JobDetail指向discountJob的execute()方法
	 */
	@Bean
	MethodInvokingJobDetailFactoryBean jobFactoryBean() {
		MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
		bean.setTargetBeanName("discountJob");
		bean.setTargetMethod("execute");
		return bean;
	}
	/**
	 * 觸發(fā)器工廠
	 */
	@Bean
	CronTriggerFactoryBean cronTrigger() {
		CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
		// Corn表達(dá)式設(shè)定執(zhí)行時(shí)間規(guī)則
		bean.setCronExpression("0 0 8 ? * 7");
		// 執(zhí)行JobDetail
		bean.setJobDetail(jobFactoryBean().getObject());
		return bean;
	}
}

具體分析下上面的代碼:

  1. 觸發(fā)器設(shè)定的 Corn 表達(dá)式為 0 0 8 ? * 7 ,表示每周六的 08:00:00 執(zhí)行 1 次;
  2. 觸發(fā)器指定的 JobDetail 為 jobFactoryBean 工廠的一個(gè)對(duì)象,而 jobFactoryBean 指定的對(duì)象及方法為 discountJob 與 execute () ;
  3. 所以每周六的 8 點(diǎn),就會(huì)運(yùn)行 discountJob 組件的 execute () 方法 1 次;
  4. Corn 表達(dá)式和執(zhí)行任務(wù)、方法均以參數(shù)形式存在,這就意味著我們完全可以根據(jù)文件或數(shù)據(jù)庫配置動(dòng)態(tài)地調(diào)整執(zhí)行時(shí)間和執(zhí)行的任務(wù);
  5. 最后,周六 8 點(diǎn)的時(shí)候,商品都打了 5 折,別忘了促銷結(jié)束的時(shí)候恢復(fù)價(jià)格啊。

4. 小結(jié)

Spring Boot 可以利用一個(gè)簡單的注解,快速實(shí)現(xiàn)定時(shí)任務(wù)的功能。

說實(shí)話我第一次使用 @Scheduled 注解時(shí),完全被這種開箱即用型的簡潔震撼了,我的感受是:似乎不能更加簡潔了。

如果感覺 Spring Task 提供的定時(shí)任務(wù)機(jī)制還不足以滿足需求,Spring Boot 還可以方便地集成 Quartz 框架來幫忙。

開箱即用滿足不了,還可以即插即用,確實(shí)夠人性化的。