目錄
1.概述
2.Spring Boot定時任務(wù)
2.1.快速使用
2.2.cron表達(dá)式
3.業(yè)務(wù)示例
3.1.業(yè)務(wù)描述
3.2.業(yè)務(wù)實(shí)現(xiàn)
4.實(shí)現(xiàn)原理
5.自定義線程池
1.概述
在某些業(yè)務(wù)場景中,需要定時執(zhí)行一些任務(wù),有可能是定時統(tǒng)計然后生成報表,有可能是定時發(fā)起一個任務(wù)。最近在工作中就正好遇見一個定時發(fā)起問卷任務(wù)的一個業(yè)務(wù)場景,此處集合業(yè)務(wù)場景聊聊如何用spring boot來實(shí)現(xiàn)功能。
2.Spring Boot定時任務(wù)
2.1.快速使用
spring boot支持了定時任務(wù),通過很簡單的配置就可以使用。
依賴:
定時任務(wù)是spring boot框架提供的基礎(chǔ)能力之一,所以其依賴是在spring-boot-starter里面,但是一般開發(fā)的時候我們直接引入web依賴即可,web依賴中包含了spring-boot-starter。要注意的是Spring Boot 從版本1.3.0開始提供對定時任務(wù)的支持,本文用的依賴默認(rèn)是支持定時任務(wù)的版本。
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
開啟定時任務(wù):
任務(wù)內(nèi)容:
2.2.cron表達(dá)式
spring boot中是使用cron表達(dá)式來定義定時任務(wù)的執(zhí)行條件的。cron表達(dá)式由6個字段組成,分別表示秒、分、時、日、月、周幾。每個字段都可以接受特定的取值范圍或通配符來表示時間的匹配規(guī)則。
下面是cron表達(dá)式的每個字段的含義和可接受的取值:
- 秒(0-59)
- 分鐘(0-59)
- 小時(0-23)
- 日(1-31)
- 月(1-12或JAN-DEC)
- 周幾(0-7或SUN-SAT,其中0和7都表示周日)
除了具體的取值范圍,cron表達(dá)式還支持一些特殊字符和符號:
- 星號(*):表示匹配任意值。例如,使用星號在秒字段中,表示任務(wù)在每一秒都會被觸發(fā)。
- 問號(?):僅在日期和周幾字段中使用,表示不指定具體的值。如果你想在日期字段中匹配任意值,但同時又想在周幾字段中指定具體值,就可以使用問號。
- 斜線(/):用于指定增量。例如,在分鐘字段中使用5/10,表示從第5分鐘開始,每隔10分鐘觸發(fā)一次。
- 逗號(,):用于列舉多個值。例如,在周幾字段中使用1,3,5,表示任務(wù)在周一、周三和周五觸發(fā)。
- 連接符(-):用于指定范圍。例如,在小時字段中使用9-17,表示任務(wù)在9點(diǎn)到17點(diǎn)之間觸發(fā)。
以下是一些示例cron表達(dá)式的用法:
-
0 0 0 * * *
:每天凌晨執(zhí)行任務(wù) -
0 0/5 * * * *
:每隔5分鐘執(zhí)行任務(wù) -
0 0 9-17 * * MON-FRI
:周一至周五的9點(diǎn)到17點(diǎn)之間每小時執(zhí)行任務(wù)
3.業(yè)務(wù)示例
3.1.業(yè)務(wù)描述
需求:
- 管理人員新建一個問卷調(diào)查任務(wù),任務(wù)在固定時間發(fā)起,固定時間結(jié)束。
- 任務(wù)開始后,系統(tǒng)的每個用戶會收到一份問卷
- 任務(wù)結(jié)束后,用戶不可再答題
實(shí)體關(guān)系:
整個實(shí)體關(guān)系很簡單,就是一個任務(wù)一種模板,一個任務(wù)多份問卷,一個模板N份問卷,一個問卷一個用戶。
問卷里記錄了模板內(nèi)容、任務(wù)ID、用戶ID。
3.2.業(yè)務(wù)實(shí)現(xiàn)
問卷調(diào)查任務(wù)類:
這里使用JPA去訪問數(shù)據(jù)庫
@Entity
@Table(name = "survey_task")
public class SurveyTask {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String taskName;
private LocalDateTime startTime;
// 其他屬性和對應(yīng)的getter/setter方法
}
定時任務(wù):
這里只是簡單的寫了一下定時任務(wù)的邏輯,實(shí)際的代碼實(shí)現(xiàn)從簡。
@Service
public class SurveyTaskScheduler {
@Autowired
private SurveyTaskRepository surveyTaskRepository;
@Scheduled(cron = "0 0 0 * * *") // 每天凌晨執(zhí)行
public void distributeSurveyTemplates() {
LocalDate today = LocalDate.now();
LocalDateTime startOfDay = today.atStartOfDay();
List<SurveyTask> surveyTasks = surveyTaskRepository.findByStartTime(startOfDay);
for (SurveyTask task : surveyTasks) {
// 根據(jù)任務(wù)分發(fā)問卷模板給用戶的邏輯
// ...
System.out.println("分發(fā)問卷模板給用戶: " + task.getTaskName());
}
}
}
啟動定時任務(wù):
@SpringBootApplication
@EnableScheduling
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
4.實(shí)現(xiàn)原理
spring boot的定時任務(wù)底層其實(shí)就是使用線程池來實(shí)現(xiàn)的,其流程如下:
-
首先,Spring Boot 根據(jù)配置文件中的屬性創(chuàng)建一個 TaskScheduler(如果沒有自定義線程池會使用默認(rèn)線程池ThreadPoolTaskScheduler)實(shí)例作為調(diào)度器,并設(shè)置線程池的相關(guān)屬性,例如核心線程數(shù)、最大線程數(shù)、隊列容量等。
-
當(dāng)應(yīng)用啟動時,Spring Boot 會掃描所有被
@Scheduled
注解標(biāo)記的方法,并將這些方法注冊為定時任務(wù)。 -
當(dāng)定時任務(wù)的觸發(fā)條件滿足時,調(diào)度器將從線程池中選擇一個線程來執(zhí)行任務(wù)。
-
執(zhí)行任務(wù)時,調(diào)度器會通過 TaskExecutor(默認(rèn)為 ThreadPoolTaskExecutor)實(shí)例來執(zhí)行任務(wù)。它會從線程池中選擇一個空閑的線程來執(zhí)行被
@Scheduled
注解標(biāo)記的方法。 -
執(zhí)行完成后,線程將返回到線程池中等待下一次調(diào)度。
5.自定義線程池
如果在 Spring Boot 中沒有顯式配置線程池,那么會使用默認(rèn)的線程池配置。但是有時候可能我們也需要自定義線程池,自定義線程池的示例如下:文章來源:http://www.zghlxwxcb.cn/news/detail-466764.html
@Configuration
public class CustomThreadPoolConfig {
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10); // 設(shè)置線程池大小
// 設(shè)置其他線程池屬性,如隊列容量、線程名前綴等
return scheduler;
}
}
?文章來源地址http://www.zghlxwxcb.cn/news/detail-466764.html
到了這里,關(guān)于Spring Boot定時任務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!