Dependency Injection이란 2개의 오브젝트가 있고 하나의 오브젝트가 다른 오브젝트를 의존하고 있는데 항상 제 3의 오브젝트가 그 으존 관계를 설정해주는 구조로 동작하는 것을 말한다. 그래서 3이다.
스프링에서는 비동기 요청의 응답을 핸들링하기 위한 클래스가 별도로 존재합니다.
void
Future<T>
ListenableFuture<T>

CompletableFuture<T>

여기서 @Async 어노테이션을 사용하는건 상관없지만 잘 생각하고 사용해야 합니다.
@Async(”myExecutor”) 혹은 Executor, ExecutorService, TaskExecutor 타입의 빈을 등록하면 해당 스레드 풀을 사용하도록 해준다.@Async 메서드에서 스레드 생성 동작

무엇인가를 기다리느라 서블릿 요청 처리를 완료하지 못하는 경우를 위해서 등장했습니다.


위에서 말한 Servlet 3.0+ 비동기 요청 처리 기반의 @MVC입니다. 아래는 리턴 타입 종류입니다.
Callable<T>
WebAsyncTask<T>
DeferredResult<T>

@Async + ListenableFuture<T> + DeferredResult<T>

스프링이 위처럼 쓰는걸 알고 ListenableFuture<T> 을 만들어서 위 과정을 생략할 수 있다.

두 가지 이상인 경우는 방법이 없다. 비동기 작업 결과를 어떻게 다음 비동기 작업의 인자로 넘길까. 이 땐 앞선 콜백 + DeferredResult 방식으로 돌아가야 합니다. 이는 콜백 헬을 야기한다. 이는 ListenableFuture에서 피할수는 없다.

비동기 작업의 결합은 CompletableFuture<T>를 사용하면 해결 가능하다.

COmpletabelFuture 결과를 받고 thenCompose()를 통해 다시 비동기 작업을 이어간다.
람다식과 메서드 레퍼런스를 통해 좀더 간결하게 만들 수 있다.
