1. 개요
이 튜토리얼에서는 Spring @Scheduled 어노테이션 을 사용하여 작업을 구성하고 예약하는 방법을 설명합니다.
@Scheduled 로 메서드에 어노테이션을 달기 위해 따라야하는 간단한 규칙은 다음과 같습니다.
- 메서드는 void 반환 유형을 가져야합니다.
- 메소드는 매개 변수를 허용하지 않아야합니다.
2. 예약 지원 활성화
Spring에서 스케줄링 작업 및 @Scheduled 어노테이션에 대한 지원을 활성화하기 위해 Java enable-style 어노테이션을 사용할 수 있습니다.
@Configuration
@EnableScheduling
public class SpringConfig {
...
}
반대로 XML에서도 똑같이 할 수 있습니다.
<task:annotation-driven>
3. 고정 된 지연으로 작업 예약
고정 된 지연 후에 실행되도록 작업을 구성하여 시작하겠습니다.
@Scheduled(fixedDelay = 1000)
public void scheduleFixedDelayTask() {
System.out.println(
"Fixed delay task - " + System.currentTimeMillis() / 1000);
}
이 경우 마지막 실행 종료와 다음 실행 시작 사이의 기간이 고정됩니다. 작업은 항상 이전 작업이 완료 될 때까지 대기합니다.
이 옵션은 다시 실행하기 전에 이전 실행을 완료해야하는 경우에 사용해야합니다.
4. 고정 된 속도로 작업 예약
이제 고정 된 시간 간격으로 작업을 실행 해 보겠습니다.
@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTask() {
System.out.println(
"Fixed rate task - " + System.currentTimeMillis() / 1000);
}
이 옵션은 각 작업 실행이 독립적 인 경우에 사용해야합니다.
예약 된 작업은 기본적으로 병렬로 실행되지 않습니다. 따라서 fixedRate 를 사용하더라도 이전 작업이 완료 될 때까지 다음 작업이 호출되지 않습니다.
예약 된 작업에서 병렬 동작을 지원하려면 @Async 어노테이션 을 추가해야합니다 .
@EnableAsync
public class ScheduledFixedRateExample {
@Async
@Scheduled(fixedRate = 1000)
public void scheduleFixedRateTaskAsync() throws InterruptedException {
System.out.println(
"Fixed rate task async - " + System.currentTimeMillis() / 1000);
Thread.sleep(2000);
}
}
이제이 비동기 작업은 이전 작업이 완료되지 않은 경우에도 매초마다 호출됩니다.
5. 고정 금리 vs 고정 지연
Spring의 @Scheduled 어노테이션을 사용하여 예약 된 작업을 실행할 수 있지만 fixedDelay 및 fixedRate 속성을 기반으로 실행 특성이 변경됩니다.
fixedDelay의 속성 확인의 지연이 있음을하게 n 개의 작업의 실행 및 작업의 다음 실행 시작 시간 종료 시간 사이의 밀리 초.
이 속성은 작업의 한 인스턴스 만 항상 실행되도록해야 할 때 특히 유용합니다. 종속 직업의 경우 매우 유용합니다.
있도록, fixedRate의 속성은 모든에서 예약 된 작업 실행 n 개의 밀리 초. 작업의 이전 실행을 확인하지 않습니다.
이것은 작업의 모든 실행이 독립적 일 때 유용합니다. 메모리와 스레드 풀의 크기를 초과 할 것으로 예상하지 않는다면 fixedRate 가 매우 편리 할 것입니다.
수신 작업이 빨리 완료되지 않으면 "메모리 부족 예외"로 끝날 수 있습니다.
6. 초기 지연으로 작업 예약
다음으로 지연 (밀리 초)으로 작업을 예약 해 보겠습니다.
@Scheduled(fixedDelay = 1000, initialDelay = 1000)
public void scheduleFixedRateWithInitialDelayTask() {
long now = System.currentTimeMillis() / 1000;
System.out.println(
"Fixed rate task with one second initial delay - " + now);
}
이 예제에서 fixedDelay 와 initialDelay 를 모두 사용하는 방법에 유의하십시오 . 작업은 initialDelay 값 이후에 처음 실행되며 fixedDelay 에 따라 계속 실행됩니다 .
이 옵션은 작업에 완료해야하는 설정이있을 때 편리합니다.
7. Cron 표현식을 사용하여 작업 예약
때로는 지연과 속도가 충분하지 않으며 작업 일정을 제어하기 위해 cron 표현식의 유연성이 필요합니다.
@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
long now = System.currentTimeMillis() / 1000;
System.out.println(
"schedule tasks using cron jobs - " + now);
}
이 예에서는 매월 15 일 오전 10시 15 분에 실행되도록 작업을 예약하고 있습니다.
기본적으로 Spring은 cron 표현식에 서버의 현지 시간대를 사용합니다. 그러나 zone 속성을 사용하여이 시간대를 변경할 수 있습니다 .
@Scheduled(cron = "0 15 10 15 * ?", zone = "Europe/Paris")
이 구성을 사용하면 Spring은 매월 15 일 오전 10시 15 분에 파리 시간으로 실행되도록 어노테이션이 달린 메서드를 예약합니다.
8. 일정 매개 변수화
이러한 일정을 하드 코딩하는 것은 간단하지만 일반적으로 전체 앱을 다시 컴파일하고 다시 배포하지 않고도 일정을 제어 할 수 있어야합니다.
작업의 구성을 외부화하기 위해 Spring 표현식을 사용하고이를 속성 파일에 저장할 것입니다.
fixedDelay의 작업 :
@Scheduled(fixedDelayString = "${fixedDelay.in.milliseconds}")
있도록, fixedRate의 작업 :
@Scheduled(fixedRateString = "${fixedRate.in.milliseconds}")
크론 표현을 기반으로 작업 :
@Scheduled(cron = "${cron.expression}")
9. XML을 사용하여 예약 된 작업 구성
Spring은 예약 된 작업을 구성하는 XML 방식도 제공합니다. 이를 설정하기위한 XML 구성은 다음과 같습니다.
<!-- Configure the scheduler -->
<task:scheduler id="myScheduler" pool-size="10" />
<!-- Configure parameters -->
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="beanA" method="methodA"
fixed-delay="5000" initial-delay="1000" />
<task:scheduled ref="beanB" method="methodB"
fixed-rate="5000" />
<task:scheduled ref="beanC" method="methodC"
cron="*/5 * * * * MON-FRI" />
</task:scheduled-tasks>
10. 런타임에 동적으로 지연 또는 속도 설정
일반적으로 @Scheduled 어노테이션 의 모든 속성은 Spring 컨텍스트 시작시 한 번만 해결되고 초기화됩니다.
따라서 Spring에서 @Scheduled 어노테이션을 사용할 때 런타임에 fixedDelay 또는 fixedRate 값을 변경할 수 없습니다 .
그러나 해결 방법이 있습니다. Spring의 SchedulingConfigurer를 사용 하면 지연 또는 속도를 동적으로 설정할 수있는 더 많은 사용자 정의 가능한 방법을 제공합니다 .
Spring 구성 인 DynamicSchedulingConfig 를 만들고 SchedulingConfigurer 인터페이스를 구현해 보겠습니다 .
@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {
@Autowired
private TickService tickService;
@Bean
public Executor taskExecutor() {
return Executors.newSingleThreadScheduledExecutor();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
taskRegistrar.addTriggerTask(
new Runnable() {
@Override
public void run() {
tickService.tick();
}
},
new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext context) {
Optional<Date> lastCompletionTime =
Optional.ofNullable(context.lastCompletionTime());
Instant nextExecutionTime =
lastCompletionTime.orElseGet(Date::new).toInstant()
.plusMillis(tickService.getDelay());
return Date.from(nextExecutionTime);
}
}
);
}
}
알다시피 ScheduledTaskRegistrar # addTriggerTask 메서드 의 도움으로 Runnable 작업과 Trigger 구현을 추가하여 각 실행이 끝난 후 nextExecutionTime 을 다시 계산할 수 있습니다 .
또한 DynamicSchedulingConfig 에 @EnableScheduling 으로 어노테이션을 달아 스케줄링이 작동하도록합니다.
결과적으로 TickService # tick 메서드가 각 지연 시간 후에 실행되도록 예약했으며 , 이는 getDelay 메서드에 의해 런타임에 동적으로 결정 됩니다.
11. 결론
이 기사에서는 @Scheduled 어노테이션 을 구성하고 사용하는 방법에 대해 설명했습니다 .
스케줄링을 활성화하는 프로세스와 스케줄링 작업 패턴을 구성하는 다양한 방법에 대해 설명했습니다. 또한 지연 및 속도를 동적으로 구성하는 해결 방법도 보여주었습니다.
위에 표시된 예 는 GitHub 에서 찾을 수 있습니다 .
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/spring-scheduled-tasks
'Java' 카테고리의 다른 글
Spring 프로필(Profiles) 설정방법(예제) (0) | 2021.03.13 |
---|---|
Spring REST API + OAuth2 + Angular (0) | 2021.03.13 |
Spring Boot의 유효성 검사(validation 예제) (0) | 2021.03.12 |
자바에서 HashMap 초기화 (0) | 2021.03.12 |
Spring @Value 사용방법(예제) (0) | 2021.03.12 |