Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

che01 님의 블로그

Spring @EnableScheduling과 @Scheduled 동작 원리 본문

Spring

Spring @EnableScheduling과 @Scheduled 동작 원리

che01 2025. 7. 13. 00:12

@EnableScheduling 애너테이션의 역할

@EnableScheduling을 설정 클래스에 추가하면 Spring은 내부적으로 스케줄링 관련 인프라를 자동으로 구성한다.

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

내부 동작 메커니즘

1. ScheduledExecutorService 등록

Spring은 @EnableScheduling이 활성화되면 ScheduledExecutorService를 빈으로 등록한다. 기본적으로 단일 스레드 풀을 사용하는 ThreadPoolTaskScheduler를 생성한다.

2. @Scheduled 메서드 스캔 및 등록

애플리케이션 컨텍스트 초기화 시점에 Spring은 모든 빈을 스캔하여 @Scheduled 애너테이션이 붙은 메서드를 찾는다. 이후 각 메서드의 스케줄링 정보를 추출하여 ScheduledTaskRegistrar에 등록한다.

3. 백그라운드 스레드 실행

등록된 스케줄링 작업들은 메인 애플리케이션 로직과는 완전히 분리된 별도의 스레드에서 실행된다. 이 스레드는 애플리케이션이 종료될 때까지 지속적으로 유지된다.

@Scheduled 사용 예시

@Component
public class ScheduledTasks {
    
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("Current time: " + new Date());
    }
    
    @Scheduled(fixedDelay = 3000)
    public void doSomething() {
        // 이전 실행 완료 후 3초 대기
    }
    
    @Scheduled(cron = "0 0 12 * * ?")
    public void dailyTask() {
        // 매일 12시에 실행
    }
}

기본 실행 방식의 특징

순차 실행

기본적으로 여러 @Scheduled 메서드가 있다면 하나의 스레드에서 순차적으로 실행된다. 이는 한 작업이 오래 걸리면 다른 작업의 실행이 지연될 수 있음을 의미한다.

예외 처리

@Scheduled 메서드에서 예외가 발생하면 해당 작업만 중단되고 다른 스케줄링 작업에는 영향을 주지 않는다. 하지만 반복 실행되는 작업의 경우 예외 발생 시 해당 작업의 이후 실행이 중단될 수 있다.

TaskExecutor 커스터마이징

멀티스레드 환경에서 스케줄링 작업을 실행하려면 TaskExecutor 를 커스터마이징할 수 있다.

@Configuration
@EnableScheduling
public class SchedulingConfig implements SchedulingConfigurer {
    
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }
    
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        scheduler.setThreadNamePrefix("scheduled-task-");
        scheduler.initialize();
        return scheduler;
    }
}

스레드 풀 관리

생명주기

  • 애플리케이션 시작 시: 스레드 풀 생성 및 초기화
  • 런타임: 백그라운드에서 지속적으로 스케줄링 작업 실행
  • 애플리케이션 종료 시: 스레드 풀 정리 및 리소스 해제

리소스 관리

Spring은 애플리케이션 종료 시 스케줄링 스레드를 자동으로 정리한다. 하지만 커스텀 TaskScheduler를 사용하는 경우 적절한 shutdown 로직을 구현해야 한다.

주의사항

동시성 문제

여러 스케줄링 작업이 동일한 자원에 접근하는 경우 동시성 문제가 발생할 수 있다. 이런 경우 동기화 메커니즘을 적용해야 한다.

메모리 누수

장기간 실행되는 스케줄링 작업에서 메모리 누수가 발생하지 않도록 주의해야 한다. 특히 정적 참조나 캐시 사용 시 주의가 필요하다.

트랜잭션 처리

@Scheduled 메서드에서 데이터베이스 작업을 수행하는 경우 @Transactional을 함께 사용하여 트랜잭션 경계를 명확히 해야 한다.