- Spring은 비동기 작업의 실행을 위한 인터페이스를 제공합니다.
- Spring은 이러한 인터페이스를 구현하는 구현체도 제공합니다.
- 스레드 풀을 지원하거나 애플리케이션 서버 환경 내에서의 CommonJ에 위임할 수 있습니다
1. The Spring TaskExecutor Abstraction
TaskExecutor Types
- Spring은 다양한 요구 사항과 환경에 맞게 선택할 수 있는 다양한 TaskExecutor 구현체를 제공합니다.
SyncTaskExecutor
- 호출을 비동기적으로 실행하지 않습니다.
- 각 호출은 호출하는 쓰레드에서 직접 실행됩니다.
- 주로 멀티 쓰레딩이 필요하지 않은 상황, 예를 들어 간단한 테스트 케이스에서 사용됩니다.
SimpleAsyncTaskExecutor
- 이 구현체는 쓰레드를 재사용하지 않습니다.
- 각 호출마다 새로운 쓰레드를 시작합니다.
- 동시성 제한을 지원하여 제한을 초과하는 호출이 슬롯이 사용 가능해질 때까지 차단됩니다.
ConcurrentTaskExecutor
- 이 구현체는 java.util.concurrent.Executor 인스턴스의 어댑터입니다.
- ThreadPoolTaskExecutor는 Executor 구성 매개 변수를 bean 속성으로 노출하는 대안이 있습니다.
- ConcurrentTaskExecutor를 직접 사용할 필요는 거의 없습니다.
ThreadPoolTaskExecutor
- 이 구현체는 가장 일반적으로 사용됩니다.
- java.util.concurrent.ThreadPoolExecutor를 구성하는 bean 속성을 노출하고 TaskExecutor로 감싸줍니다.
- 다른 종류의 java.util.concurrent.Executor에 적응해야 한다면, ConcurrentTaskExecutor를 사용하는 것이 좋습니다.
2. Annotation Support for Scheduling and Asynchronous Execution
Enable Scheduling Annotations
- Spring 프로젝트에서 비동기 작업 및 스케쥴링 작업을 쉽게 활성화하고 관리할 수 있게 도와줍니다.
@EnableAsync
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}
- 이 어노테이션을 사용하면 @Async 어노테이션을 사용한 메서드가 비동기적으로 실행될 수 있게 됩니다.
- 즉, 메서드 호출이 즉시 반환되고, 실제 메서드 실행은 별도의 쓰레드에서 비동기적으로 수행됩니다.
- 더 세밀한 제어가 필요한 경우 AsyncConfigurer 인터페이스를 구현할 수 있습니다.
The @Async annotation
기본사용
@Async
void doSomething() {
// this will be run asynchronously
}
- @Async 어노테이션을 메서드에 제공하면 그 메서드는 비동기적으로 호출됩니다.
인자가 있는 @Async
@Async
void doSomething(String s) {
// this will be run asynchronously
}
- @Async 어노테이션을 사용한 메서드는 인자를 가질 수 있습니다.
- 이러한 메서드는 일반적인 방식으로 런타임에 호출자에 의해 호출됩니다.
반환이 있는 @Async
@Async
Future<String> returnSomething(int i) {
// this will be run asynchronously
}
- @Async 어노테이션을 사용하여 값 반환 메서드도 비동기적으로 호출할 수 있습니다.
- 그러나 이러한 메서드는 Future 형식의 반환 값이 필요합니다.
주의사항
- 라이프사이클 콜백과 함께 사용할 수 없습니다.
public class SampleBeanImpl implements SampleBean {
@Async
void doSomething() {
// ...
}
}
public class SampleBeanInitializer {
private final SampleBean bean;
public SampleBeanInitializer(SampleBean bean) {
this.bean = bean;
}
@PostConstruct
public void initialize() {
bean.doSomething();
}
}
Executor Qualification with @Async
@Async("otherExecutor")
void doSomething(String s) {
// this will be run asynchronously by "otherExecutor"
}
- @Async를 메서드에 지정하면, 비동기 지원을 활성화할 때 구성된 실행자(executor)가 사용됩니다.
- 기본 실행자가 아닌 다른 실행자를 사용하여 특정 메서드를 실행해야 할 때 value 속성을 사용하여 실행자를 지정할 수 있습니다.
Exception Management with @Async
@Async 어노테이션을 사용하여 메서드를 비동기적으로 실행할 때는 예외 처리에 주의해야 합니다.
Future-typed 반환 값이 있는 경우
- 메서드 실행 중에 발생한 예외는 Future 결과에 대한 get을 호출할 때 발생합니다.
- try-catch 블록으로 쉽게 처리할 수 있습니다.
void 반환 타입인 경우
- 예외는 캐치되지 않아 전달될 수 없습니다.
- 이런 예외를 처리하기 위해 AsyncUncaughtExceptionHandler를 제공할 수 있습니다.
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
// handle exception
}
}
- AsyncUncaughtExceptionHandler를 구현하고 있으며, 비동기 메서드에서 캐치되지 않은 예외를 처리합니다.
설정
AsyncUncaughtExceptionHandler 정의
- AsyncConfigurer
- XML의 <task:annotation-driven/> 요소를 사용
출처