Skip to main content

Spring의 @Async와 비동기 처리 흐름 완전 정복

· 3 min read
hwayoung kim
소주같은 개발자

Spring에서는 @Async 어노테이션을 활용하여 간단하게 비동기 작업을 처리할 수 있습니다.
이 포스트에서는 @Async의 작동 원리, 설정 방법, 실전 코드 예시를 모두 다룹니다.


🔍 @Async란?

@Async는 Spring Framework에서 제공하는 비동기 처리를 위한 어노테이션입니다.
이 어노테이션이 붙은 메서드는 별도의 쓰레드에서 비동기로 실행됩니다.

  • 기본적으로 SimpleAsyncTaskExecutor 또는 ThreadPoolTaskExecutor를 사용
  • 리턴 타입은 void, Future<T>, CompletableFuture<T>, ListenableFuture<T> 등이 가능

⚙️ 기본 설정 방법

  1. @EnableAsync 어노테이션을 메인 설정 클래스에 추가
  2. @Async를 사용할 메서드에 적용
  3. (선택) Executor Bean을 직접 설정하여 스레드 풀 튜닝 가능

🧱 설정 예제

📌 의존성 (Spring Boot 프로젝트)

<!-- spring-boot-starter 포함 시 별도 필요 없음 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

📌 비동기 설정 클래스

@Configuration
@EnableAsync
public class AsyncConfig {

@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("Async-Executor-");
executor.initialize();
return executor;
}
}

✅ 서비스 예제 코드

@Service
public class NotificationService {

@Async
public void sendEmail(String to) {
try {
Thread.sleep(3000); // 모의 대기
System.out.println("[Email] Sent to: " + to + " on thread " + Thread.currentThread().getName());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
@RestController
@RequiredArgsConstructor
public class NotificationController {

private final NotificationService notificationService;

@PostMapping("/notify")
public String notifyUser(@RequestParam String email) {
notificationService.sendEmail(email);
return "이메일 전송 요청 완료";
}
}

🧠 유의사항

  • @Async프록시 기반이므로, 같은 클래스 내의 메서드 호출 시 작동하지 않음
  • 예외 발생 시 AsyncUncaughtExceptionHandler로 처리 가능
  • 보통 반환값이 없고 오래 걸리는 작업에 적합 (예: 알림, 로깅, 백그라운드 통계 처리 등)

✍️ 실전 활용 예시

  • 비동기 이메일/알림 전송
  • 슬로우 로그 저장
  • Redis 캐시 갱신 트리거
  • 대용량 배치 연산 후 후처리

🔗 참고 링크

Reference