참고 블로그 : 덕분에 이해 잘 되었습니다.
- 클라이언트의 요청을 디스패처 서블릿이 받음
- 디스패처 서블릿은 가장 먼저 요청을 받는 프론트 컨트롤러입니다. 서블릿 컨텍스트(웹 컨텍스트)에서 필터들을 지나 스프링 컨텍스트에서 디스패처 서블릿이 가장 먼저 요청을 받게됩니다.
- 요청 정보를 통해 요청을 위임할 컨트롤러를 찾음
- 디스패처 서블릿은 요청 정보를 바탕으로, 요청을 처리할 컨트롤러를 찾고 해당 메소드를 호출해야 합니다.
오늘날에는 주로 @Controller와 @RequestMapping 관련 어노테이션을 조합하여 컨트롤러를 생성하므로, 요청을 처리할 컨트롤러는 주로 HandlerMapping의 구현체 중 하나인 RequestMappingHandlerMapping가 찾아줍니다.
해당 객체는 내부에서 HashMap으로 (요청 정보, 처리 대상)을 관리하고 있어서, 요청 정보를 Key로 사용하여 요청을 처리할 대상을 찾아옵니다. 이때 요청을 처리할 대상은 컨트롤러가 아닌 컨트롤러를 가지고 있는 HandlerMethod 객체입니다. HandlerMethod를 갖는 이유는 컨트롤러와 컨트롤러의 메소드 등을 포함해 부가적인 정보들이 더욱 필요하기 때문입니다.
그리고 찾아온 HandlerMethod를 HandlerMethodExecutionChain으로 감싸서 반환화는데, 그 이유는 컨트롤러로 요청을 넘겨주기 전에 처리해야 하는 인터셉터 등을 포함하기 위해서입니다.
HandlerMethod : @RequestMapping과 그 하위 어노테이션(@GetMapping, @PostMapping 등)이 붙은 메소드의 정보를 추상화한 객체
- 요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함
- 디스패처 서블릿은 컨트롤러로 요청을 직접 위임하는 것이 아니라 HandlerAdapter를 통해 어댑터 패턴을 적용해 컨트롤러로 요청을 위임합니다. 이때 어댑터 인터페이스를 통해 컨트롤러를 호출하는 이유는 컨트롤러의 구현 방식이 다양하기 때문입니다.
스프링은 꽤나 오래 전에(2004년) 만들어진 프레임워크로, 트렌드를 굉장히 잘 따라갑니다. 프로그래밍 흐름에 맞게 스프링 역시 변화를 따라가게 되었는데, 그러면서 다양한 코드 작성 방식을 지원하게 되었습니다. 과거에는 컨트롤러를 Controller 인터페이스로 구현하였는데, Ruby On Rails가 어노테이션 기반으로 관례를 이용한 프로그래밍을 내세워 혁신을 일으키면서 스프링 역시 이를 도입하게 되었습니다.
그래서 다양하게 작성되는 컨트롤러에 대응하기 위해 스프링은 HandlerAdapter라는 어댑터 인터페이스를 통해 어댑터 패턴을 적용함으로써 컨트롤러의 구현 방식에 상관없이 요청을 위임할 수 있도록 하였습니다.
- 핸들러 어댑터가 컨트롤러로 요청을 위임함
- 핸들러 어댑터가 컨트롤러로 요청을 넘기기 전에 공통적인 전처리 과정이 필요합니다. 요청에 매칭되는 인터셉터들도 실행을 시키고, @RequestParam, @RequestBody 등으로 파라미터를 준비하는 ArgumentResolver도 실행하는 등의 다양한 공통 작업들이 수행됩니다. 이러한 전처리 작업들이 완료되면 파라미터 값들과 함께 컨트롤러로 요청을 위임합니다.
비지니스 로직을 처리함
- 이후에 컨트롤러는 서비스를 호출하고 우리가 작성한 비지니스 로직들이 진행됩니다.
- 컨트롤러가 반환값을 반환함
- 비지니스 로직이 처리된 후에는 컨트롤러가 반환값을 반환합니다. 응답 데이터를 사용하는 경우에는 주로 ResponseEntity를 반환하게 되고, 응답 페이지를 보여주는 경우라면 String으로 View의 이름을 반환할 수도 있습니다.
- 핸들러 어댑터가 반환값을 처리함
핸들러 어댑터는 컨트롤러로부터 받은 반환값을 응답 처리기인 ReturnValueHandler가 후처리한 후에 디스패처 서블릿으로 돌려줍니다. 만약 컨트롤러가 ResponseEntity를 반환하면 HttpEntityMethodProcessor가 MessageConverter를 사용해 응답 객체를 직렬화하고 응답 상태(HttpStatus)를 설정합니다. 만약 컨트롤러가 View 이름을 반환하면 View를 반환하기 위한 준비 작업을 처리합니다.
- 서버의 응답을 클라이언트로 반환함
- 디스패처 서블릿을 통해 반환되는 응답은 다시 필터들을 거쳐 클라이언트에게 반환됩니다. 이때 응답이 데이터라면 그대로 반환되지만, 응답이 화면이라면 View의 이름에 맞는 View를 찾아서 반환해주는 ViewResolver가 적절한 화면을 내려줍니다.