Develop
Spring Framework의 Scheduled 스케줄 동적으로 실행 방법
issuemaker99
2025. 2. 17. 15:19
728x90
Spring에서 @Scheduled을 동적으로 시작/중지하려면 TaskScheduler나 ScheduledFuture를 사용해야 합니다.
기본적으로 @Scheduled은 고정된 스케줄로 실행되므로 실행 중지나 동적 시작이 어렵습니다. 하지만 ScheduledExecutorService 또는 ThreadPoolTaskScheduler를 사용하면 동적으로 스케줄을 제어할 수 있습니다.
🔹 동적으로 스케줄 시작 및 중지하는 방법
1️⃣ ThreadPoolTaskScheduler 사용
Spring의 ThreadPoolTaskScheduler를 활용하여 동적으로 작업을 실행 및 중단할 수 있습니다.
이 방법을 사용하면 REST API 또는 UI 버튼을 통해 스케줄링을 제어할 수 있습니다.
✅ 1. 설정: TaskScheduler 빈 생성
먼저, 동적 스케줄링을 제어할 ThreadPoolTaskScheduler 빈을 설정합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class SchedulerConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5); // 최대 5개의 스레드 사용 가능
scheduler.setThreadNamePrefix("DynamicScheduler-");
scheduler.initialize();
return scheduler;
}
}
✅ 2. 동적 스케줄링을 관리할 서비스 클래스
이제 TaskScheduler를 활용하여 스케줄을 동적으로 관리하는 서비스를 만듭니다.
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import java.util.concurrent.ScheduledFuture;
@Service
public class DynamicSchedulerService {
private final ThreadPoolTaskScheduler taskScheduler;
private ScheduledFuture<?> scheduledTask;
public DynamicSchedulerService(ThreadPoolTaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
// ✅ 스케줄 시작
public void startSchedule() {
if (scheduledTask == null || scheduledTask.isCancelled()) {
scheduledTask = taskScheduler.schedule(this::runTask, new CronTrigger("0/5 * * * * *")); // 5초마다 실행
System.out.println("스케줄이 시작되었습니다.");
}
}
// ✅ 스케줄 중단
public void stopSchedule() {
if (scheduledTask != null) {
scheduledTask.cancel(false);
System.out.println("스케줄이 중단되었습니다.");
}
}
// 실행할 작업
private void runTask() {
System.out.println("동적 스케줄 실행: " + System.currentTimeMillis());
}
}
설명
- ThreadPoolTaskScheduler를 사용하여 동적으로 스케줄링 작업을 실행 및 취소합니다.
- ScheduledFuture<?> scheduledTask를 통해 현재 실행 중인 작업을 추적합니다.
- startSchedule() → 크론 표현식 (0/5 * * * * *)으로 5초마다 작업 실행
- stopSchedule() → 실행 중인 작업을 취소
✅ 3. REST API로 스케줄 제어
위의 DynamicSchedulerService를 활용하여 스케줄을 시작/중지하는 컨트롤러를 추가합니다.
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/scheduler")
public class SchedulerController {
private final DynamicSchedulerService schedulerService;
public SchedulerController(DynamicSchedulerService schedulerService) {
this.schedulerService = schedulerService;
}
// ✅ 스케줄 시작
@PostMapping("/start")
public String startScheduler() {
schedulerService.startSchedule();
return "스케줄이 시작되었습니다.";
}
// ✅ 스케줄 중단
@PostMapping("/stop")
public String stopScheduler() {
schedulerService.stopSchedule();
return "스케줄이 중단되었습니다.";
}
}
테스트 방법
# 스케줄 시작
curl -X POST http://localhost:8080/scheduler/start
# 스케줄 중지
curl -X POST http://localhost:8080/scheduler/stop
또는 Postman에서 POST 요청을 보내도 됩니다.
📌 결과 확인
🔹 /scheduler/start 호출 후
스케줄이 시작되었습니다.
동적 스케줄 실행: 1700000000000
동적 스케줄 실행: 1700000005000
동적 스케줄 실행: 1700000010000
...
5초마다 작업 실행
🔹 /scheduler/stop 호출 후
스케줄이 중단되었습니다.
실행이 중단됨
🔥 추가 기능
1️⃣ UI에서 시작/중지 버튼 추가
- 프론트엔드(React/Vue)에서 버튼을 만들어 API를 호출하면 쉽게 스케줄을 제어할 수 있습니다.
<button onclick="fetch('/scheduler/start', { method: 'POST' })">스케줄 시작</button>
<button onclick="fetch('/scheduler/stop', { method: 'POST' })">스케줄 중단</button>
✅ 정리
방법 | 설명 |
@Scheduled | 기본적인 스케줄링이 가능하지만 동적 제어 불가능 |
ThreadPoolTaskScheduler | 동적으로 스케줄 시작/중단 가능, 크론 표현식 활용 가능 |
LIST