@Async: 별도 ThreadPool 생성이 필요 없는 비동기 처리

상위 맥락

03. Async와 Caching < 01. AOP와 빈 관리 원리 < 01. Spring MVC1 기초와 아키텍처 < MVC < Spring < Web

핵심 정리

@Async는 스프링에서 비동기 처리를 선언적으로 적용할 수 있게 해주는 기능입니다. 일반 자바 코드에서 비동기 처리를 하려면 Thread, Runnable, Executor, ThreadPool 등을 직접 다뤄야 합니다. 스프링은 이 복잡한 스레드 관리 로직을 TaskExecutor와 AOP 프록시 뒤로 숨깁니다.

동작 원리

메서드에 @Async가 붙어 있고, 설정에서 @EnableAsync가 활성화되어 있으면 스프링은 해당 빈을 프록시로 감쌉니다. 외부에서 그 메서드를 호출하면 프록시가 호출을 가로채고, 실제 작업을 TaskExecutor에 위임합니다. 이때 작업은 별도의 스레드에서 실행될 수 있습니다.

개발자는 직접 ThreadPool을 만들지 않고도 다음과 같은 구조를 얻습니다.

  • 메서드에는 @Async만 선언합니다.
  • 비동기 실행 전략은 TaskExecutor가 담당합니다.
  • 비즈니스 로직은 스레드 생성 코드와 분리됩니다.

장점

@Async의 핵심 장점은 비동기 처리라는 시스템 서비스를 비즈니스 코드에서 분리한다는 점입니다. 비즈니스 메서드는 자신의 작업만 표현하고, 스레드 생성 및 실행 위임은 스프링 인프라가 처리합니다.

또한 TaskExecutor 구현체를 바꾸면 실행 방식을 조정할 수 있습니다. 자료에서는 ThreadPoolTaskExecutor, SimpleAsyncTaskExecutor, SyncTaskExecutor 같은 구현체가 언급됩니다. 실제 비즈니스 코드를 바꾸지 않고 실행 전략만 바꿀 수 있다는 점이 중요합니다.

주의할 점

@Async는 프록시를 통과하는 외부 호출에서만 동작합니다. 같은 클래스 내부에서 this.someAsyncMethod()처럼 호출하면 프록시를 우회하므로 비동기로 실행되지 않고 동기적으로 실행될 수 있습니다. 이 문제는 내부 호출 문제와 직접 연결됩니다.

한 문장 요약

@Async는 스레드 관리 코드를 직접 작성하지 않고도, 프록시와 TaskExecutor를 통해 비동기 실행을 선언적으로 적용하게 해줍니다.

핵심 연결

AOP, 프록시와 함께 읽으면 좋습니다.