Spring/Spring

[Spring][Integration] 1. Task Execution: @Async

noahkim_ 2023. 10. 16. 02:16
  • Spring에서 비동기 작업을 실행할 때 쓰는 실행기 인터페이스
  • Spring은 이러한 인터페이스를 구현하는 구현체도 제공합니다.
    • 스레드 풀을 지원하거나 애플리케이션 서버 환경 내에서의 CommonJ에 위임할 수 있습니다

 

1. The Spring TaskExecutor Abstraction

TaskExecutor Types

  • Spring은 다양한 요구 사항과 환경에 맞게 선택할 수 있는 다양한 TaskExecutor 구현체를 제공합니다.
구현체 비동기 실행  스레드 재사용 특징 주 사용 상황
SyncTaskExecutor X 호출한 스레드에서 직접 실행 테스트, 디버깅
SimpleAsyncTaskExecutor X 호출마다 새 스레드 생성
동시성 제한 가능
간단한 비동기 작업
ConcurrentTaskExecutor 감싼 Executor에 따름 Executor를 Spring TaskExecutor로 감싸는 어댑터 기존 Executor를 Spring에서 써야 할 때
ThreadPoolTaskExecutor O ThreadPoolExecutor 기반
pool 설정을 Bean 속성으로 제공
실무에서 가장 일반적으로 사용

 

2. Annotation Support for Scheduling and Asynchronous Execution

@EnableAsync

  • Spring 프로젝트에서 비동기 작업 및 스케쥴링 작업을 쉽게 활성화하고 관리할 수 있게 도와줍니다.
  •  @Async 어노테이션을 사용한 메서드가 비동기적으로 실행될 수 있게 됩니다.
  • ✅ 더 세밀한 제어가 필요한 경우 AsyncConfigurer 인터페이스를 구현할 수 있습니다.
  • ➡️ 메서드 호출이 즉시 반환되고, 실제 메서드 실행은 별도의 쓰레드에서 비동기적으로 수행됩니다.

 

설정) @EnableAsync

더보기
@Configuration
@EnableAsync
@EnableScheduling
public class AppConfig {
}

 

The @Async annotation

  • @Async 어노테이션을 메서드에 제공하면 그 메서드는 비동기적으로 호출됩니다.
  • ✅ 값 반환 메서드도 비동기적으로 호출할 수 있습니다. (Future 형식의 반환타입만 가능)
  • ⚠️ 라이프사이클 콜백과 함께 사용할 수 없습니다.

 

예시) 기본사용

더보기
@Async
void doSomething() {
	// this will be run asynchronously
}

 

예시) 반환이 있는 @Async

더보기
@Async
Future<String> returnSomething(int i) {
	// this will be run asynchronously
}

 

예시) 라이프사이클 사용 불가

더보기
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를 메서드에 지정하면, 비동기 지원을 활성화할 때 구성된 실행자(executor)가 사용됩니다.
  • 기본 실행자가 아닌 다른 실행자를 사용하여 특정 메서드를 실행해야 할 때 value 속성을 사용하여 실행자를 지정할 수 있습니다.

 

설정) executor

더보기
@Async("otherExecutor")
void doSomething(String s) {
	// this will be run asynchronously by "otherExecutor"
}

 

Exception Management with @Async

  • @Async 어노테이션을 사용하여 메서드를 비동기적으로 실행할 때는 예외 처리에 주의해야 합니다.

 

Future-typed 반환 값이 있는 경우
  • 메서드 실행 중에 발생한 예외는 Future 결과에 대한 get을 호출할 때 발생합니다. 
  • try-catch 블록으로 쉽게 처리할 수 있습니다.

 

void 반환 타입인 경우
  • 예외는 캐치되지 않아 전달될 수 없습니다.
  • 이런 예외를 처리하기 위해 AsyncUncaughtExceptionHandler를 제공할 수 있습니다.

 

예시) AsyncUncaughtExceptionHandler 사용

더보기
public class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {

	@Override
	public void handleUncaughtException(Throwable ex, Method method, Object... params) {
		// handle exception
	}
}
  • 비동기 메서드에서 캐치되지 않은 예외를 처리합니다.

 

설정

AsyncUncaughtExceptionHandler 정의
  • AsyncConfigurer
  • XML의 <task:annotation-driven/> 요소를 사용

 

 

 

출처