Job scheduling trong Spring Boot
spring
67
spring boot
67
job scheduling
1
quartz
1
White

Nguyễn Tuấn Anh viết ngày 15/01/2020

Job scheduling là một công việc chúng ta thường hay gặp trong khi xây dựng các ứng dụng. Để thực hiện job scheduling trong Spring Boot, chúng ta có thể áp dụng một trong hai cách sau:

  1. Sử dụng annotation @Scheduled
  2. Sử dụng thư viện Quartz

...

1. Sử dụng annotation @Scheduled

1.1. Enable scheduling

Với cách này, trước tiên chúng ta cần phải enable scheduling trong Spring Boot bằng cách thêm annotation @EnableScheduling ở configuration class:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

1.2. Annotation @Scheduled

Annotatinon @Scheduled được khai báo bên trên method xử lý job.

Method này phải đảm bảo 2 yêu cầu sau:

  • Trả về void.
  • Không được ném ra các ngoại lệ.

Các tham số thường dùng của @Scheduled là:

long initialDelay

Khoảng thời gian được tính từ thời điểm startup của ứng dụng Spring Boot cho đến thời điểm bắt đầu của lần thực thi đầu tiên của method xử lý job. Đơn vị: millisecond.

long fixedDelay

Chúng ta có thể dùng kết hợp initialDelay với fixedDelay. Lúc này, thời điểm của các lần thực thi method xử lý job sẽ là:

  • Lần thực thi thứ 1: sau initialDelay
  • Lần thực thi thứ 2: sau khi lần thực thi thứ 1 chấm dứt + fixedDelay
  • Lần thực thi thứ 3: sau khi lần thực thi thứ 2 chấm dứt + fixedDelay
  • Lần thực thi thứ 4: sau khi lần thực thi thứ 3 chấm dứt + fixedDelay
  • ...

long fixedRate

Chúng ta có thể dùng kết hợp initialDelay với fixedRate. Lúc này, thời điểm của các lần thực thi method xử lý job sẽ là:

  • Lần thực thi thứ 1: sau initialDelay
  • Lần thực thi thứ 2: sau initialDelay + fixedRate
  • Lần thực thi thứ 3: sau initialDelay + 2 * fixedRate
  • Lần thực thi thứ 4: sau initialDelay + 3 * fixedRate
  • ...

String cron

Biểu thức crontab: method xử lý job sẽ được thực thi tại đúng thời điểm thỏa mãn biểu thức crontab.

Chú ý: Phải đảm bảo một và chỉ một trong 3 tham số initialDelay, fixedDelaycron xuất hiện khi khai báo @Scheduled.

1.3. Ví dụ

Mình sẽ viết một job cứ 5 giây in thời gian hiện tại 1 lần.

PrintNowService.java

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class PrintNowService {

    @Scheduled(fixedDelay = 5000)
    public void printNow() {
        System.out.println(LocalDateTime.now());
    }
}

Chạy ứng dụng Spring Boot và chúng ta sẽ thấy kết quả như sau:

2020-01-15T10:22:52.437
2020-01-15T10:22:57.437
2020-01-15T10:23:02.444
...

2. Sử dụng thư viện Quartz

2.1. Spring Boot Quartz

Quartz sử dụng các đối tượng Trigger, JobJobDetail để thực hiện job scheduling.

Để tích hợp thư viện Quartz trong Spring Boot, chúng ta sẽ khai báo Quartz starter trong pom.xml:

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

2.2. Ví dụ

Mình sẽ viết một job cứ 5 giây in 1 số ngẫu nhiên.

PrintRandomService.java: lớp xử lý logic của job.

import org.springframework.stereotype.Service;

import java.util.concurrent.ThreadLocalRandom;

@Service
public class PrintRandomService {

    public void printRandom() {
        System.out.println(ThreadLocalRandom.current().nextInt());
    }
}

PrintRandomJob.java: bean đại diện cho job và phải kế thừa org.springframework.scheduling.quartz.QuartzJobBean.

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class PrintRandomJob extends QuartzJobBean {

    @Autowired
    private PrintRandomService printRandomService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        printRandomService.printRandom();
    }
}

JobConfiguration.java: lớp cấu hình JobDetailTrigger của job.

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JobConfiguration {

    @Bean
    public JobDetail printRandomJobDetail() {
        return JobBuilder
                .newJob(PrintRandomJob.class)
                .withIdentity(JobKey.jobKey("printRandom"))
                .storeDurably()
                .build();
    }

    @Bean
    public Trigger printRandomJobTrigger() {
        return TriggerBuilder
                .newTrigger()
                .forJob(printRandomJobDetail())
                .withIdentity(TriggerKey.triggerKey("printRandom"))
                .withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?"))
                .build();
    }
}

Chạy ứng dụng Spring Boot và chúng ta sẽ thấy kết quả như sau:

-1727615121
878308058
-803885137
...
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Nguyễn Tuấn Anh

30 bài viết.
242 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
52 41
MyContact là một ứng dụng mà mình thường viết mỗi khi học một ngôn ngữ hay công nghệ mới. MyContact chỉ là một ứng dụng CRUD đơn giản, cho phép ngư...
Nguyễn Tuấn Anh viết 3 năm trước
52 41
White
29 14
Hướng dẫn lập trình Spring Security Trong bài viết lần này, mình sẽ giúp các bạn bước đầu tìm hiểu (Link) thông qua xây dựng các chức năng: Đăng ...
Nguyễn Tuấn Anh viết 3 năm trước
29 14
White
17 1
Giới thiệu Spring Framework Trong bài viết này, mình sẽ giới thiệu cho các bạn về một trong những Java EE framework rất nổi bật và phổ biến hiện n...
Nguyễn Tuấn Anh viết 3 năm trước
17 1
Bài viết liên quan
White
2 0
I used Spring boot, Hibernate few times back then at University, I'v started using it again recently. In this (Link), I want to check how Spring J...
Rey viết 12 tháng trước
2 0
White
0 0
Giới thiệu Trong bài hôm nay chúng ta sẽ tìm hiểu cách handle request POST của Spring Boot. Trước đó, bạn nên biết 1. 「Spring Boot 8」Tạo Web He...
https://loda.me viết 8 tháng trước
0 0
White
1 0
Giới thiệu Yêu cầu bạn phải đọc bài viết về @Conditional trước: 1. Spring Boot] Hướng dẫn tạo Bean có điều kiện với @Conditional]lin...
https://loda.me viết 8 tháng trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
30 bài viết.
242 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!