일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- spring
- Spring JPA
- aws secretmanager
- @FunctionalInterface
- elasticsearch
- b3-propagation
- java list
- map
- jpa
- SpringMVC
- spring MVC
- spring3 spring2 traceid
- Spring Boot
- traceasynccustomautoconfiguration
- DeferredImportSelector
- ResponseBody
- awssecretsmanagerpropertysources
- CompletableFuture
- list
- java.util.list
- Sleuth
- micrometer tracing
- HashMap
- EnableWebMvc
- java
- java lambda
- asyncconfigurer
- traceId
- asynccustomautoconfiguration
- kotlin
- Today
- Total
du.study기록공간
Spring Scheduling @EnableScheduling, @Scheduled 본문
이번엔 스프링에서 사용하고 있는 Scheduling에 대해서 기록해보려합니다.
현재 저희 프로젝트에서는 일정시간단위로 반복되는 작업 처리 방법 중 하나로 해당 Scheduled를 사용하고 있습니다.
오늘 갑자기 코드를 보면서 해당 @Scheduled 가 어떻게 실행되고 set되는지가 궁금하여 조금 간략하게나마 여기에 기입해보려합니다.
먼저 Spring에서 Scheduling을 사용하려면 @Configuration을 선언한 설정파일과 같이 @EnableScheduling를 선언해야합니다.
@Configuration
@EnableScheduling
public class ScheduleConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}
}
@EnableScheduling 내부를 보면 다음과 같이 ScheduledAnnotationBeanPostProcessor Bean을 등록하게 됩니다.
@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();
}
}
Bean으로 생성하는 ScheduledAnnotationBeanPostProcessor에서 핵심적인 역할을 하게됩니다.
postProcessAfterInitialization() 메소드에서 @Scheduled을 선언한 메소드를 수집,해당 스케쥴들을 processScheduled을통해 등록을 하게됩니다. ( 간단하게 ScheduledAnnotationBeanPostProcessor 가 스케쥴 테스크등록의 핵심 클레스입니다. )
해당 클레스에서 스케쥴러 쓰레드 등록하는 코드또한 지원합니다.
@Configuration
@EnableScheduling
public class ScheduleConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}
}
private void finishRegistration() {
.....
Map<String, SchedulingConfigurer> beans =
((ListableBeanFactory) this.beanFactory).getBeansOfType(SchedulingConfigurer.class);
List<SchedulingConfigurer> configurers = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(configurers);
for (SchedulingConfigurer configurer : configurers) {
configurer.configureTasks(this.registrar);
}
.....
@EnableScheduling 와는 별도로 SchedulingConfigurer를 implements해줍니다. 해당 선언을 통해 해당 클레스는 SchedulingConfigurer.class 조회에 포함되며, 해당 선언을 세팅할 수 있게됩니다.
public void setScheduler(@Nullable Object scheduler) {
if (scheduler == null) {
this.taskScheduler = null;
}
else if (scheduler instanceof TaskScheduler) {
this.taskScheduler = (TaskScheduler) scheduler;
}
else if (scheduler instanceof ScheduledExecutorService) {
this.taskScheduler = new ConcurrentTaskScheduler(((ScheduledExecutorService) scheduler));
}
else {
throw new IllegalArgumentException("Unsupported scheduler type: " + scheduler.getClass());
}
}
아래 해당 setScheduler 코드를 보면 하부 ScheduledExecutorService를 등록하여 쓰레드를 할당해줍니다.
해당과정을 통해서 선언한 Schedule 등록, 스레드 세팅 까지 완료가됩니다. ( 너무간단하게 적은거 같긴한데..)
마지막으로 해당 스케쥴링을 어디서 실행해 주는가는 ThreadPoolExecutor에 있는 runWorker 에 의하여 while문 루프를 돌면서 스케쥴을 주기적으로 실행하게 됩니다..
음 ... 정리하면서도 너무 간단하게 정리한것같아 조금씩 해당포스팅은 업데이트를 해야할 것 같습니다.
'스프링' 카테고리의 다른 글
Spring boot AutoConfiguration 동작방식2 - DeferredImportSelector (0) | 2021.01.10 |
---|---|
Spring boot Auto Configuration 동작방식 (0) | 2021.01.03 |
Spring boot Web embedded Container(server) 변경 (0) | 2020.05.10 |
Spring boot @SpringBootApplication (0) | 2020.05.07 |
@Value는 어디서 set이 되는걸까? (0) | 2020.04.05 |