컨트롤러 메소드 실행:(개발자가 작성한) 컨트롤러 메서드가 실행되어 비즈니스 로직을 처리하고, View 또는 ResponseEntity 객체를 반환합니다.
뷰 리졸버와 뷰 렌더링 (뷰 반환 시)
뷰 이름 리졸빙: 컨트롤러가 문자열 형태의 뷰 이름을 반환하면, 디스패처 서블릿은 ViewResolver를 사용하여 이 이름에 해당하는 실제 뷰 객체를 찾습니다.
모델 데이터 준비: 컨트롤러에서 반환된 모델 데이터는 뷰에 전달되어 데이터를 화면에 표시할 수 있도록 합니다.
뷰 렌더링: 준비된 모델 데이터와 뷰 객체를 사용하여 최종적인 HTML 페이지를 생성해 반환합니다.
ResponseEntity 반환 (HTTP 응답 직접 제어 시)
HTTP 응답 생성: 컨트롤러 메서드가 ResponseEntity 객체를 반환하는 경우, 이 객체는 HTTP 응답의 본문(Body), 상태 코드, 헤더 등을 직접 제어할 수 있습니다.
응답 전송: ResponseEntity에 설정된 정보에 따라 HTTP 응답이 구성되고, 클라이언트에게 직접 전송됩니다. 이 경우 별도의 뷰 리졸빙이나 렌더링 과정은 거치지 않습니다.
어떻게 요청을 위임할 컨트롤러를 찾을까?
스프링 MVC에서 URL 정보를 통해 요청을 위임할 컨트롤러를 찾는 과정은 핸들러 매핑(Handler Mapping)을 통해 이루어집니다. 스프링에는 여러 핸들러 매핑 전략이 존재하지만, 최근의 컨트롤러는 대부분 '@Controller', '@RestController' 어노테이션으로 구성하는 방식이기 때문에, 'RequestMappingHandlerMapping'이 가장 일반적으로 사용됩니다.
'RequestMappingHandlerMapping' 구현체는 요청 URL 패턴을 분석해, '@RequestMapping' 어노테이션에 지정된 패턴과 일치하는지 검사합니다. 검사 이후, 가장 정확하게 일치하는 핸들러(실제 요청을 처리할 컨트롤러 메서드)를 선택해HandlerExecutionChain 객체에 담아 반환하고, 이를 받은 디스패처 서블릿이 핸들러를 실행하기 위한 핸들러 어댑터를 선택하는 등 요청 처리를 이어갑니다.
💡핸들러를 HandlerExecutionChain 객체에 담아 반환하는 이유 요청을 처리하기 위해 결정된 핸들러뿐만 아니라, 요청 처리 전·후에 실행되어야 할 인터셉터(interceptor) 목록도 함께 관리하기 위해서이다. 이 체인으로 인터셉터 목록을 관리하고, 인터셉터의 실행 순서를 관리해 일관된 처리 흐름을 보장한다.
핸들러 어댑터는 어떻게 파라미터 바인딩 / 응답 직렬화 등을 처리할까?
- 파라미터 바인딩
'HandlerMethodArgumentResolver' 인터페이스를 구현한 ArgumentResolver를 사용하여 다양한 종류의 메서드 파라미터를 처리합니다.
@RequestParam, @PathVariable 어노테이션은 URL 쿼리 파라미터나 경로 변수를 메소드 파라미터로 바인딩하고, @RequestBody 등 요청 본문에 포함된 데이터는 'HttpMessageConverter'를 사용하여 요청 본문의 내용을 자바 객체로 변환합니다.
- 응답 직렬화
'HandlerMethodReturnValueHandler' 인터페이스를 구현한 ReturnValueHandler를 사용하여 메서드의 반환 값에 따라 적절한 응답 생성 전략을 선택합니다.
컨트롤러 메서드가 @ResponseBody나 ResponseEntity 타입 값을 반환한 경우, 'RequestResponseBodyMethodProcessor'가 반환값 처리를 담당합니다.