@Scheduled 어노테이션은 스프링 프레임워크에서 메소드를 주기적으로 실행하도록 스케줄링하는 데 사용됩니다.
기본적인 사용 방법은 다음과 같습니다:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("현재 시간: " + new Date());
}
}
@Async와 함께 사용하여 비동기적으로 작업을 실행할 수 있습니다.작업 완료 후 지정된 시간만큼 대기한 후 다음 작업을 시작합니다.
@Scheduled(fixedDelay = 5000) // 5초 지연
public void scheduleFixedDelayTask() {
// 작업 내용
}
이전 작업의 시작 시간으로부터 지정된 시간이 지나면 새 작업을 시작합니다.
@Scheduled(fixedRate = 5000) // 5초마다
public void scheduleFixedRateTask() {
// 작업 내용
}
애플리케이션 시작 후 첫 실행까지의 지연 시간을 설정합니다.
@Scheduled(fixedRate = 5000, initialDelay = 1000) // 1초 후 시작, 이후 5초마다
public void scheduleFixedRateWithInitialDelayTask() {
// 작업 내용
}
복잡한 스케줄링 패턴을 지정할 수 있습니다.
@Scheduled(cron = "0 15 10 * * ?") // 매일 오전 10시 15분에 실행
public void scheduleTaskUsingCronExpression() {
// 작업 내용
}
스케줄링을 사용하려면 @EnableScheduling 어노테이션을 구성 클래스에 추가해야 합니다:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class SchedulerConfig {
}
런타임에 스케줄을 변경해야 하는 경우, SchedulingConfigurer를 구현할 수 있습니다:
@Configuration
@EnableScheduling
public class DynamicSchedulerConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(
() -> {
// 실행할 작업
},
triggerContext -> {
// 다음 실행 시간을 결정하는 로직
return new CronTrigger("0 15 10 * * ?").nextExecutionTime(triggerContext);
}
);
}
}
@Async와 함께 사용하여 스케줄된 작업을 비동기적으로 실행할 수 있습니다:
@EnableAsync
@Configuration
@EnableScheduling
public class SchedulerConfig {
}
@Component
public class AsyncScheduledTasks {
@Async
@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTaskAsync() throws InterruptedException {
System.out.println("Fixed rate task async - " + System.currentTimeMillis() / 1000);
Thread.sleep(2000);
}
}
스케줄된 작업을 테스트할 때는 awaitility 라이브러리를 사용하면 편리합니다:
import static org.awaitility.Awaitility.*;
import static java.util.concurrent.TimeUnit.*;
@SpringBootTest
class ScheduledTasksTest {
@Test
void testScheduledTask() {
await().atMost(10, SECONDS).untilAsserted(() -> {
// 스케줄된 작업이 실행되었는지 확인하는 로직
});
}
}
fixedRate를 사용할 때 작업 실행 시간이 간격보다 길어지면 시간 드리프트가 발생할 수 있습니다.@Scheduled 어노테이션은 스프링 애플리케이션에서 반복적인 작업을 쉽게 구현할 수 있게 해줍니다. 데이터 정리, 보고서 생성, 알림 전송 등 다양한 주기적 작업에 활용될 수 있습니다. 그러나 동시성, 성능, 오류 처리 등을 신중히 고려하여 사용해야 합니다.
@EnableScheduling
@Async
@Configuration
@Component
@EnableAsync