??作者簡介,普修羅雙戰(zhàn)士,一直追求不斷學習和成長,在技術的道路上持續(xù)探索和實踐。
??多年互聯(lián)網(wǎng)行業(yè)從業(yè)經(jīng)驗,歷任核心研發(fā)工程師,項目技術負責人。
??歡迎 ??點贊?評論?收藏
?? SpringBoot 領域知識 ??
鏈接 | 專欄 |
---|---|
SpringBoot 專業(yè)知識學習一 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習二 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習三 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習四 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習五 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習六 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習七 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習八 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習九 | SpringBoot專欄 |
SpringBoot 專業(yè)知識學習十 | SpringBoot專欄 |
本文將詳細介紹如何在 Spring Boot 中實現(xiàn)定時任務,并涵蓋了控制層、服務層、數(shù)據(jù)訪問層、XML和YAML配置的使用方式。我們將從數(shù)據(jù)庫創(chuàng)建表開始,一步一步地實現(xiàn)這些功能,并提供注意事項。最后,我們將總結整個過程。
在 Spring Boot 中實現(xiàn)定時任務功能
1. 創(chuàng)建數(shù)據(jù)庫表
為了實現(xiàn)定時任務的功能,首先需要創(chuàng)建一個數(shù)據(jù)庫表。我們可以創(chuàng)建一個名為 task
的表,包含以下四個字段:
- id:自增ID
- name :定時任務的名稱
- description :定時任務描述
- dueDate :定時任務結束執(zhí)行的時間
- completed:定時任務是否完成
創(chuàng)建執(zhí)行定時任務的數(shù)據(jù)庫表可以按照以下 SQL 語句來進行:
CREATE TABLE `task` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`dueDate` datetime DEFAULT NULL,
`completed` boolean DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
該表包含了 id
、name
、description
、 dueDate
和 completed
五個字段。其中,id
為自增主鍵,name
表示定時任務的名稱,description
表示定時任務描述,dueDate
表示定時任務結束執(zhí)行的時間,completed
表示定時任務是否完成??梢愿鶕?jù)實際需求修改表結構。
2. 添加依賴
在 pom.xml
文件中添加定時任務依賴 spring-boot-starter-quartz
:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<properties>
<java.version>11</java.version>
<spring.boot.version>2.6.1</spring.boot.version>
</properties>
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- Spring Boot Starter Quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- Other dependencies -->
<!-- ... -->
</dependencies>
<build>
<plugins>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
這樣我們就可以使用 Quartz 框架來實現(xiàn)定時任務。
3. 創(chuàng)建定時任務實體類和 DAO 層
3.1 首先創(chuàng)建一個Task實體類,用于表示定時任務的屬性。
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDateTime;
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
private LocalDateTime dueDate;
private boolean completed;
// 構造函數(shù)、Getter 和 Setter 方法
public Task() {
}
public Task(String name, String description, LocalDateTime dueDate) {
this.name = name;
this.description = description;
this.dueDate = dueDate;
this.completed = false;
}
// Getter 和 Setter 方法省略...
// 其他屬性和方法省略...
}
在這個示例中,Task
實體類有以下屬性:
-
id
:任務的唯一標識符,使用自動生成的遞增值。 -
name
:任務的名稱。 -
description
:任務的描述。 -
dueDate
:任務的截止日期。 -
completed
:任務是否已完成的標志。
注意,在這個示例中,使用了 Java 8 的 LocalDateTime
類型來表示日期和時間。您可以根據(jù)具體需求選擇適合的日期時間類型。
請根據(jù)您的具體需求修改屬性、構造函數(shù)和方法。接下來,您可以創(chuàng)建一個與數(shù)據(jù)庫進行交互的 DAO 層。
3.2 創(chuàng)建一個 TaskDao 接口
定義對定時任務的基本增刪改查方法,如 addTask
、deleteTask
、updateTask
、findTaskById
等。
import java.time.LocalDateTime;
import java.util.List;
public interface TaskDao {
void addTask(Task task);
void deleteTask(long taskId);
void updateTask(long taskId, String name, String description, LocalDateTime dueDate, boolean completed);
Task findTaskById(long taskId);
List<Task> findTasks();
}
在這個示例中,TaskDao
定義了如下基本操作:
-
addTask
:添加一個新的任務。 -
deleteTask
:刪除指定的任務。 -
updateTask
:更新任務的名稱、描述、截止日期和完成狀態(tài)。 -
findTaskById
:根據(jù)任務 ID 查找任務。 -
findTasks
:獲取當前所有的任務列表。
可以根據(jù)具體需求添加、修改或刪除方法。但是,通常來說,一個 DAO 接口需要定義基本的 CRUD 操作,即增加、刪除、更新、查詢。我們建議您采用命名規(guī)范,例如按照方法名構造 SQL 語句,或者使用注解進行映射。另外,為了管理和維護代碼,我們建議您將實現(xiàn)代碼放在另外的類中,例如命名為 TaskDaoImpl
。
4. 創(chuàng)建 Service 層
4.1 在 TaskService
類中實現(xiàn)定時任務的操作方法,包括添加、刪除、修改和查詢方法等。
4.2 在方法中,可以通過調用 TaskDao
中的方法來完成對數(shù)據(jù)庫的操作,如創(chuàng)建新任務、刪除任務、修改任務等。
4.3 可以使用 @Autowired
注解將 TaskDao
注入到 TaskService
中,方便調用。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class TaskService {
private final TaskDao taskDao;
@Autowired
public TaskService(TaskDao taskDao) {
this.taskDao = taskDao;
}
public void addTask(String name, String description, LocalDateTime dueDate) {
Task task = new Task(name, description, dueDate);
taskDao.addTask(task);
}
public void deleteTask(long taskId) {
taskDao.deleteTask(taskId);
}
public void updateTask(long taskId, String name, String description, LocalDateTime dueDate, boolean completed) {
Task existingTask = taskDao.findTaskById(taskId);
if (existingTask != null) {
existingTask.setName(name);
existingTask.setDescription(description);
existingTask.setDueDate(dueDate);
existingTask.setCompleted(completed);
taskDao.updateTask(existingTask);
} else {
throw new IllegalArgumentException("Task not found with ID: " + taskId);
}
}
public Task findTaskById(long taskId) {
return taskDao.findTaskById(taskId);
}
public List<Task> findTasks() {
return taskDao.findTasks();
}
}
在這個示例中,TaskService
類使用了依賴注入將 TaskDao
對象注入進來,并實現(xiàn)了以下操作方法:
-
addTask
:創(chuàng)建一個新的任務,并調用TaskDao
的addTask
方法將其添加到數(shù)據(jù)庫中。 -
deleteTask
:刪除指定 ID 的任務,并調用TaskDao
的deleteTask
方法進行刪除操作。 -
updateTask
:根據(jù)指定 ID 更新任務的屬性,并調用TaskDao
的updateTask
方法進行更新操作。 -
findTaskById
:根據(jù)指定 ID 查找并返回任務對象。 -
findTasks
:獲取當前所有的任務列表。
請根據(jù)您的具體需求修改代碼,并確保將適當?shù)腻e誤處理和驗證邏輯添加到每個方法中。此外,確保適當?shù)靥幚硪蕾囎⑷耄允?TaskDao
正確地注入到 TaskService
類中。
請注意,在這個示例中,使用了 Spring 的 @Service
和 @Autowired
注解來實現(xiàn)依賴注入和服務的聲明。如果您沒有使用 Spring 或其他類似的框架,您可以手動創(chuàng)建和管理相關對象的實例。
5. 創(chuàng)建 Controller 層
5.1 在 TaskController
類中定義定時任務的 API 接口,使用 RESTful 風格。
5.2 可以使用 @Autowired
注解將 TaskService
注入到 TaskController
中,方便調用 TaskService
中的方法。
5.3 實現(xiàn)增刪改查等控制器方法,通過 HTTP 請求來調用相應的方法。
當您在 Controller 層中創(chuàng)建的時候,可以考慮如下代碼示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
@RestController
@RequestMapping("/tasks")
public class TaskController {
private final TaskService taskService;
@Autowired
public TaskController(TaskService taskService) {
this.taskService = taskService;
}
@PostMapping
public ResponseEntity<Task> addTask(@RequestBody TaskRequest taskRequest) {
taskService.addTask(taskRequest.getName(), taskRequest.getDescription(), taskRequest.getDueDate());
return new ResponseEntity<>(HttpStatus.CREATED);
}
@DeleteMapping("/{taskId}")
public ResponseEntity<Task> deleteTask(@PathVariable long taskId) {
taskService.deleteTask(taskId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@PutMapping("/{taskId}")
public ResponseEntity<Task> updateTask(@PathVariable long taskId, @RequestBody TaskRequest taskRequest) {
taskService.updateTask(taskId, taskRequest.getName(), taskRequest.getDescription(), taskRequest.getDueDate(), taskRequest.isCompleted());
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/{taskId}")
public ResponseEntity<Task> findTaskById(@PathVariable long taskId) {
Task task = taskService.findTaskById(taskId);
if (task != null) {
return new ResponseEntity<>(task, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@GetMapping
public ResponseEntity<List<Task>> findTasks() {
List<Task> tasks = taskService.findTasks();
return new ResponseEntity<>(tasks, HttpStatus.OK);
}
}
在這個示例中,TaskController
類使用了 Spring 的 MVC 注解來定義不同的 HTTP 請求處理方法:
-
@RestController
:聲明這是一個 RESTful 控制器。 -
@RequestMapping("/tasks")
:指定該控制器處理的 URL 前綴。 -
@PostMapping
:處理 HTTP POST 請求,并調用addTask
方法創(chuàng)建任務。 -
@DeleteMapping("/{taskId}")
:處理 HTTP DELETE 請求,并調用deleteTask
方法刪除指定 ID 的任務。 -
@PutMapping("/{taskId}")
:處理 HTTP PUT 請求,并調用updateTask
方法更新指定 ID 的任務。 -
@GetMapping("/{taskId}")
:處理 HTTP GET 請求,并調用findTaskById
方法獲取指定 ID 的任務。 -
@GetMapping
:處理 HTTP GET 請求,并調用findTasks
方法獲取所有任務列表。
請根據(jù)您的具體需求修改代碼,并確保將適當?shù)腻e誤處理和驗證邏輯添加到每個方法中。此外,確保適當?shù)靥幚硪蕾囎⑷耄允?TaskService
正確地注入到 TaskController
類中。
在這個示例中,TaskRequest
是一個用于接收客戶端請求的數(shù)據(jù)傳輸對象(DTO),根據(jù)您的需求,您可以根據(jù)實際情況創(chuàng)建適合自己的 DTO 類來接收和傳遞數(shù)據(jù)。
請注意,在這個示例中,使用了 Spring 的注解來簡化了 RESTful API 的開發(fā),如果您不使用 Spring 框架,可以根據(jù)自己所用框架的要求來編寫 Controller 層的代碼。
6. 創(chuàng)建定時任務工具類
創(chuàng)建一個 QuartzUtil
工具類,用于創(chuàng)建定時任務實例。
使用 JobBuilder
、TriggerBuilder
等工具類,設置定時任務的屬性,如任務名稱、任務組名、任務類、觸發(fā)器類型、觸發(fā)器名稱、觸發(fā)器組名等。
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzUtil {
private static Scheduler scheduler;
static {
try {
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public static void addJob(String jobId, String jobGroup, String triggerId, String triggerGroup, Class<? extends Job> jobClass, String cronExpression) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobId, jobGroup).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerId, triggerGroup).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();
scheduler.scheduleJob(jobDetail, trigger);
}
public static void deleteJob(String jobId, String jobGroup) throws SchedulerException {
JobKey jobKey = new JobKey(jobId, jobGroup);
scheduler.deleteJob(jobKey);
}
public static void pauseJob(String jobId, String jobGroup) throws SchedulerException {
JobKey jobKey = new JobKey(jobId, jobGroup);
scheduler.pauseJob(jobKey);
}
public static void resumeJob(String jobId, String jobGroup) throws SchedulerException {
JobKey jobKey = new JobKey(jobId, jobGroup);
scheduler.resumeJob(jobKey);
}
public static void shutdown() throws SchedulerException {
scheduler.shutdown();
}
}
使用示例:
public class TestJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("執(zhí)行定時任務...");
}
}
public class Main {
public static void main(String[] args) {
try {
// 添加一個每分鐘執(zhí)行一次的定時任務
QuartzUtil.addJob("job1", "jobGroup", "trigger1", "triggerGroup", TestJob.class, "0 * * * * ?");
Thread.sleep(10000);
// 暫停定時任務
QuartzUtil.pauseJob("job1", "jobGroup");
Thread.sleep(10000);
// 恢復定時任務
QuartzUtil.resumeJob("job1", "jobGroup");
Thread.sleep(10000);
// 刪除定時任務
QuartzUtil.deleteJob("job1", "jobGroup");
// 停止定時任務調度器
QuartzUtil.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
需要注意的是,上述示例僅為基礎示例,具體使用中還需要根據(jù)實際情況進行調整。定時任務的配置可以參考 Quartz 官方文檔,這里不再贅述。
7. 創(chuàng)建定時任務類
7.1 創(chuàng)建一個 TaskJob
類,實現(xiàn) Quartz
框架的 Job
接口,實現(xiàn)需要執(zhí)行的任務邏輯。
7.2 在 TaskJob
類中,通過重寫 execute
方法來實現(xiàn)具體的任務邏輯。
可以在 TaskJob
類中重寫 execute
方法來實現(xiàn)具體的任務邏輯。以下是一個示例:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class TaskJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
// 獲取任務參數(shù)
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String taskName = dataMap.getString("taskName");
// 需要執(zhí)行的任務邏輯
System.out.println("執(zhí)行任務:" + taskName);
// 任務完成后的操作
System.out.println("任務執(zhí)行完成");
}
}
在上述示例中,我們通過 JobDataMap
獲取了任務的參數(shù),例如 taskName
。在 execute
方法中可以編寫任意復雜的任務邏輯,您可以根據(jù)實際需求進行相應的操作,例如發(fā)送電子郵件、生成報告等。最后,您還可以在任務執(zhí)行完成后進行適當?shù)那謇聿僮骰蛴涗浲瓿蔂顟B(tài)。請根據(jù)您的具體需求在 execute
方法中編寫任務邏輯。
8. 配置定時任務
在 application.yml
文件中添加定時任務的配置:
spring:
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
這樣就可以從數(shù)據(jù)庫中讀取定時任務的配置信息,并在啟動時創(chuàng)建相應的數(shù)據(jù)庫表。
9. 測試
在啟動 Spring Boot 項目后,通過瀏覽器訪問 http://localhost:8080/task
來測試新增定時任務的功能是否生效。
10. 實現(xiàn)總結
通過以上步驟,我們成功地在 Spring Boot 中實現(xiàn)了定時任務的功能。使用 Spring Boot Starter Quartz 提供的依賴,我們可以方便地創(chuàng)建和管理定時任務。通過創(chuàng)建數(shù)據(jù)庫表、編寫實體類、DAO 層、Service 層和 Controller 層,我們實現(xiàn)了定時任務的增刪改查功能。
需要注意的是,定時任務的時間格式是 cron
表達式,需要熟悉 cron
表達式的語法規(guī)則。同時,在測試時要注意定時任務是否已經(jīng)失效,否則會影響測試結果。
總的來說,Spring Boot 提供了簡單、便捷的方式來實現(xiàn)定時任務。通過合理地使用 Spring Boot 中的各個組件,我們可以快速地開發(fā)定時任務功能,并為我們的項目提供定時任務的支持。文章來源:http://www.zghlxwxcb.cn/news/detail-805655.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-805655.html
到了這里,關于Spring Boot 中實現(xiàn)定時任務(quartz)功能實戰(zhàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!