[스프링(spring)]@EnableScheduling

allnight5·2022년 12월 8일
0

스프링

목록 보기
8/62

참조사이트1 누르면이동
스프링 3.0부터 @EnableScheduling를 선언하여 스케줄링을 활성화 시키고 @Scheduled로 스케줄링할 작업을 간단히 추가할 수 있습니다.
스프링이 어떻게 스케줄링을 활성화 시키고 @Scheduled 메서드 작업을 주기적으로 수행시키는지 알아보겠습니다.

@EnableScheduling는 스캐줄링을 사용하기 위해서 LocalTimedate를 실행시켜주기 위하여
application에 넣는 @EnableJpaAuditing과 같이 application에 넣어줘야한다.

스캐줄링을 넣어두면 정해둔 시간에 자동으로 실행이 되게된다.
스케줄링 활성화 및 실행

@Slf4j
@Configuration
@EnableScheduling // 스케줄링을 위해 추가
public class SchedulerConfig {
    @Scheduled(cron = "0/1 * * * * *")
    public void test() {
        log.info("Hello World");
    }

    public static void main(String[] args) {
        new AnnotationConfigApplicationContext(SchedulerConfig.class);
    }
}

Scheduled 인터페이스

Scheduled 인터페이스를 보면 사용법을 확인할 수 있습니다. 크론 표현식 외에도 반복 작업을 위해 다양한 방법을 제공합니다.
[사용방법]

String cron() default "";
: cron 표현식을 사용하여 특정 시간마다 동작합니다.
: ("초(second) 분(minute) 시(hour) 일(day of month) 월(month) 요일(day of week)")

long fixedDelay() default -1;
: 해당 메소드 작업이 끝난 시점 기준으로 적용한 시간마다 실행 (단위 ms)

String fixedDelayString() default "";
: fixedDelay()와 기능은 동일하며 매개 값으로 문자열을 받습니다. (application.properties에 값을 넣고 사용 가능)

long fixedRate() default -1;
: 해당 메소드 작업이 시작한 시점 기준으로 적용한 시간마다 실행 (단위 ms)

String fixedRateString() default "";
: fixedRate()와 기능은 동일하며 매개 값으로 문자열을 받습니다.

long initialDelay() default -1;
: 지연 시간을 설정할 수 있습니다. (단위 ms) -> 최초 메소드 실행 시 지연 시간

String initialDelayString() default "";
: initialDelay()와 기능은 동일하며 매개 값으로 문자열을 받습니다.

@EnableScheduling을 선언하고 빈 내부 메서드에 @Scheduled를 추가하면 간단히 스케줄링 작업을 추가할 수 있습니다.
해당 예시에선 cron표기법을 사용하여 1초마다 test()메서드가 수행되게 됩니다.

추가로 ScheduledExecutorService나 SchedulerThreadPool 빈을 등록하지 않으면 디폴트로 단일 스레드풀을 사용합니다.

2. TaskScheduler와 Trigger

스프링은 추상화로 TaskScheduler와 Trigger 인터페이스를 제공합니다.
TaskScheduler는 실제 작업을 스케줄링하고, Trigger에서 해당 스케줄링 작업을 트리거 될 시간을 계산해주는 역할을 담당하고 있습니다.
TaskScheduler의 경우 따로 스케줄러를 등록하지 않으면 ConcurrentTaskScheduler를 사용하게 됩니다.
커스텀하게 ThreadPoolTaskScheduler를 빈으로 등록하면 해당 빈을 사용하게 됩니다.
Trigger의 경우 위의 예시에서 cron 표기법을 사용하였기 때문에 CronTrigger가 사용됩니다.

3. 스케줄이 등록되고 실행되는 원리

1) ScheduledAnnotationBeanPostProcessor 등록

TaskScheduler의 경우 따로 스케줄러를 등록하지 않으면 ConcurrentTaskScheduler를 사용하게 됩니다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
} 
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {
	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
		return new ScheduledAnnotationBeanPostProcessor();
	} 
}

2) PostProcessor에서 @Scheduled 메서드 작업을 스케줄러에 등록
1. Scheduled메서드 탐색 -> 2. 스케줄러 등록
자세히 설명
1.PostProcessor.postProcessAfterInitialization에서 bean에 @Scheduled가 선언된 메서드들을 찾아 postScheduled를 호출합니다.
2.@Scheduled에 설정된 fixedDelay, fixedRate, cron등에 맞는 Task를 생성하여 ScheduledTaskRegistrar에 등록합니다.

실제로 수행할 작업은 Trigger를 통해 특정한 주기에 맞게 반복적으로 수행되어야 하는데 이러한 처리를 담당하는 곳이 ReschedulingRunnable입니다.

  1. delay계산
  2. 계산 후 수행하는 스케줄 등록
  3. 실제 스케줄러 메서드수행
  4. 다시 스케줄러를 호출하여 다음주기 작업등록

RechedulingRuunable에서 Trigger를 통해 nextExecutionTime을 계산하여 schedule -> run -> schedule가 재귀적으로 호출되면서 스케줄링된 작업이 실제로 수행됩니다.

profile
공부기록하기

0개의 댓글