IT/Spring

CompletableFuture + Spring @Async

iamhyeon 2026. 1. 2. 18:20

 

Spring에서 비동기 처리를 가장 실무적으로 사용하는 방법

Spring에서 비동기 처리를 가장 간단하게 도입하는 방법은
@Async + CompletableFuture 조합이다.

 

1. @Async란 무엇인가

@Async는 Spring이 제공하는 비동기 실행 애너테이션이다.
메서드를 별도 스레드에서 실행하도록 만들어준다.

@Async
public CompletableFuture<String> asyncMethod() {
    return CompletableFuture.completedFuture("result");
}

 

 

2. 기본 동작 구조

  • @Async가 붙은 메서드는
  • Spring이 내부적으로 TaskExecutor(ThreadPool) 에 작업을 위임
  • 호출자는 즉시 반환
  • 결과는 CompletableFuture로 받는다

Spring이 스레드 관리 + CompletableFuture가 결과 관리를 담당한다.

 

3. 반드시 Executor 설정이 필요하다

기본 설정을 사용하면 예측 불가능한 스레드 풀이 사용된다.
실무에서는 반드시 명시적으로 설정해야 한다.

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-");
        executor.initialize();
        return executor;
    }
}

 

 

4. @Async + CompletableFuture 조합 예시

@Async
public CompletableFuture<User> findUserAsync(Long userId) {
    User user = userRepository.findById(userId);
    return CompletableFuture.completedFuture(user);
}

호출부:

CompletableFuture<User> future = userService.findUserAsync(1L);

 

 

5. 주의사항 

❗ 같은 클래스 내부 호출은 @Async가 적용되지 않는다

this.asyncMethod(); // 동기 실행됨

반드시 Spring Proxy를 통해 호출해야 한다.

 

❗ 트랜잭션과 함께 사용할 때 주의

  • @Async 메서드는 새로운 스레드
  • @Transactional 범위가 분리됨
  • Lazy Loading, 영속성 컨텍스트 주의 필요

 

6. 언제 이 조합이 적합한가

  • 이메일 발송, 알림 전송
  • 외부 API 호출
  • 로그 적재
  • 메인 로직과 분리된 후처리 작업

 

반응형