개요
기존에 진행하고 있던 프로젝트에서 일정 주기마다 반복적으로 작업을 수행해야 하는 기능이 필요하게 되었다. 해당 방법을 어떻게 구현할지 고민하던 중, Spring에서 스케줄링 기능을 제공한다는 것을 알게 되었고, 이를 활용하여 해당 기능을 쉽게 구현할 수 있었다.
이 글에서는 Spring Boot가 제공하는 스케줄링 기능에 대해 알아보고, 해당 기능을 프로젝트에 어떻게 적용했는지 설명한다.
스케줄링 설정
@EnableScheduling 설정
Spring에서 스케줄링 기능을 사용하려면 먼저 @EnableScheduling
이라는 어노테이션을 추가해야 한다. 해당 어노테이션은 Application 클래스 혹은 아래와 같이 @Configuration
이 붙은 configuation 클래스에 붙여 추가해야 한다.
@Configuration
@EnableScheduling
public class SchedulerConfig {
}
스케줄러 작성
먼저 스케줄러에서 실행할 작업을 클래스로 만들었다.
@RequiredArgsConstructor
@Service
@Transactional
public class SchedulerService {
private final VoucherRepository voucherRepository;
private final PurchasedVoucherRepository purchasedVoucherRepository;
public void updateExpired(LocalDate today) {
voucherRepository.updateAllByExpDateBefore(today);
purchasedVoucherRepository.updateAllStatusForExpired();
}
}
위 코드의 updateExpired()
메서드는 파라미터로 LocalDate
타입의 값을 전달받고, 해당 날짜보다 이전의 ExpDate 값을 가지는 모든 데이터에 대한 벌크 수정 연산을 진행한다.
이제 스케줄링이 적용될 클래스를 만들어야 한다. 이때 명심해야 할 점은, 스케줄링이 적용될 메서드의 클래스는 반드시 Bean으로 등록되어야 한다는 것이다. 이후, 스케줄링이 적용되고자 하는 메서드에 @Scheduled
어노테이션을 추가하면 된다.
아래의 코드는 매 자정마다 위에서 설명한 SchedulerService.updateExpired()
메서드를 실행하는 코드이다.
@Slf4j
@RequiredArgsConstructor
@Component
public class VoucherUpdateScheduler {
private static final String EVERY_MIDNIGHT = "0 0 0 * * *";
private final SchedulerService schedulerService;
@Scheduled(cron = EVERY_MIDNIGHT)
public void updateExpiredEveryMidnight() {
LocalDate today = LocalDate.now();
log.info("[Log] --- Voucher scheduler started ---");
log.info("[Log] Date: {}", today);
schedulerService.updateExpired(today);
}
}
추가적으로, @Scheduled
를 적용할 메서드는 아래와 같은 조건을 충족해야 한다.
- 반환 타입은 void
- 매개변수 사용 불가
@Scheduled 속성
위에 나온 코드에서 @Scheduled
확인해보면 속성이 추가되어 있는 것을 볼 수 있다.
fixedDelay, fixedDelayString
fixedDelay는 이전 작업의 종료 시점으로부터 지정한 miliseconds 시간만큼 지난 이후에 작업을 실행한다.
@Scheduled(fixedDelay = 1000)
public void do() {
...
}
@Scheduled(fixedDelayString = "1000")
public void do() {
...
}
fixedRate, fixedRateString
fixedRate는 이전 작업의 시작 시점으로부터 지정한 miliseconds 시간만큼 지난 이후에 작업을 실행한다. fixedRateString는 fixedRate와 같지만 문자열로 값을 표현하는 방식이다.
@Scheduled(fixedRate = 1000)
public void do() {
...
}
@Scheduled(fixedRateString = "1000")
public void do() {
...
}
initialDelay, initialDelayString
initialDelay는 초기 지연시간을 설정하는 속성이다.
@Scheduled(fixedRate = 5000, initialDelay = 1000)
public void do() {
...
}
위와 같이 사용할 경우, 1초의 지연시간 이후 5초마다 do()
메서드 안에 정의한 작업이 실행된다.
cron
Cron 표현식을 사용해 스케줄링 시간을 지정할 수 있다. Cron 표현식은 아래와 같이 6개의 필드로 구성된다.
Cron 표현식에 대해 더 자세히 알고 싶다면, 이 글을 읽어보는 것을 추천한다.
아래의 코드는 개인 프로젝트에서 직접 작성한 스케줄러로, 매일 자정마다 작업을 실행하기 위해 매일 자정을 나타내는 cron 표현식인 0 0 0 * * *
을 @Scheduled
어노테이션에 지정한 것을 확인할 수 있다.
@Slf4j
@RequiredArgsConstructor
@Component
public class VoucherUpdateScheduler {
private static final String EVERY_MIDNIGHT = "0 0 0 * * *";
private final SchedulerService schedulerService;
@Scheduled(cron = EVERY_MIDNIGHT)
public void updateExpiredEveryMidnight() {
LocalDate today = LocalDate.now();
log.info("[Log] --- Voucher scheduler started ---");
log.info("[Log] Date: {}", today);
schedulerService.updateExpired(today);
}
}
참고
'Spring' 카테고리의 다른 글
[Spring] Spring에서 실시간 알림 기능 구현하기 (0) | 2024.09.25 |
---|---|
[Spring] RestClient에 대하여 (0) | 2024.07.01 |
[Spring / AWS] Spring Boot 3 + AWS Lambda 사용하기 (0) | 2024.04.26 |
[Spring] Pagination 기본값 설정하기 (0) | 2024.04.03 |
[Spring] MultipartFile Bean Validation (0) | 2024.01.26 |