1) Spring MVC 요청 처리 흐름
클라이언트
- HTTP 요청 (예: GET /users)
톰캣 (Tomcat)
- HTTP 텍스트 패킷을 자바 표준 서블릿 객체로 변환 (무조건 변환된다)
HttpServletRequest(값 있음)/HttpServletResponese(빈 객체)로 변환
디스패처 서블릿 (DispatcherServlet)
- 핸들러 매핑
HandlerMapping에게 URL 조회 요청
핸들러 매핑 (HandlerMapping)
HandlerMapping은HandlerMap에서 요청 URL을 담당하는 컨트롤러를 찾는다HandlerMapping또한 서버가 실행될 때 IoC 컨테이너에 의해 자동으로Bean으로 등록된다.HandlerMapping은 생성될때 자신을 품고 있는ApplicationContext에게 지금 내부에 등록된Bean중에서@Controller나@RequestMapping어노테이션을 가진 컨트롤러Bean리스트를 뽑는다.ApplicationContext로부터 컨트롤러Bean들을 넘겨받은HandlerMapping은 각 컨트롤러 내부에 적힌 주소(@GetMapping("/users")등)를 분석하여 내부적으로 키(key)는 URL주소, 값(value)은 해당 컨트롤러Bean과메서드 객체형태로 이루어진Map을 작성합니다.- 만들어진
Map이 내부의HandlerMap이라는 테이블 입니다.
- 만들어진
- 매칭되는 결과가 있으면 해당 컨트롤러 Bean 객체의 참조값을 즉시 꺼내서
DispatcherServlet에게 리턴해줍니다
디스패처 서블릿 (DispatcherServlet)
- 핸들러 어댑터에게 이 컨트롤러 실행 요청 (서블릿 객체
HttpServletRequest(값 있음)/HttpServletResponese(빈 객체)도 함께 전달)
핸들러 어댑터 (HandlerAdapter)
- 해당 컨트롤러
Bean의 특정 메서드를 직접 호출 (HttpServletRequest값을 매개변수에 값을 넣어줌) - 이 컨트롤러Bean은 서버 구동 시점에 이미 IoC 컨테이너가 의존성 주입을 끝내둔 객체
실제 컨트롤러 Bean (Controller)
- 비즈니스 로직 수행 후 결과값(데이터 혹은 View 문자열) 반환
핸들러 어댑터 (HandlerAdapter)
- 반환값을
DispatcherServlet으로 토스
디스패처 서블릿 (DispatcherServlet)
- 리턴 타입 및 컨트롤러 종류에 따른 [2) 2 참고]
@RestController->HttpMessageConverter작동@Controller->ViewResolver& 템플릿 엔진 작동 (HTML문자열 생성)
- 가공한 데이터를
HttpServletResponese객체에 채운다. - 데이터가 채워진 기존
HttpServletResponse객체를 톰캣에게 다시 전달
톰캣 (Tomcat)
HttpServletResponse객체 내부의 내용을 꺼내어서 브라우저가 읽을 수 있는 최종 HTTP응답 패킷(text)으로 최종 조립 후 네트워크 선으로 발송
클라이언트
- 수신
2) 핵심 컴포넌트 내부 동작 및 분담 디테일
1) HttpServletRequest / HttpServletResponse 변환
- 필수성: 웹 브라우저가 보내는 HTTP 요청은 단순한 텍스트 덩어리이므로 자바 프로그램이 읽을 수 없습니다. 따라서 톰캣단에서 무조건 자바 서블릿 표준 객체로 파싱 및 변환하여 안으로 들여보내야 하기 때문입니다.
- 추상화: 개발자가 컨트롤러에서 HttpServeltRequest를 직접 가로채지 않고 변수 (Long id등)만 적어도 데이터가 바인딩 되는 이유는 핸들러 어댑터가 내부에서 이 객체를 뒤져 매개변수에 값을 자동으로 넣어주기 때문입니다.
2) 스프링과 톰캣의 최종 응답 조립
Response 객체는 매번 새로 만드는 것이 아니라 처음에 톰캣이 생성한 빈 바구니 (HttpServletResponse)를 끝까지 사용하면서 각자 역할을 나눠 조립합니다.
- 스프링(디스패처 서블릿)의 역할 -> 내용물 조립:
- 톰캣이 준 Response 객체라는 자바 바구니 내부에 데이터(Json/ Html)을 알맞게 가공해서 채워 넣는 조립을 합니다.
- @RestController: MappingJacson2HttpMessageConverter가 자바 객체를 Json 문자열로 변환하여 Response 출력 스트림에 채웁니다.
- @Controller: ViewResolver가 html파일을 찾고 템플릿 엔진이 동적 데이터를 결합하여 완성한 HTML 문자열을 Response 출력 스트림에 채웁니다.
- 톰캣(Tomcat)의 역할 -> 최종 포장 및 발송:
- 스프링이 내용물을 채워 돌려준 Response 객체를 받아서 웹 브라우저가 읽을 수 있는 HTTP응답 표준 프로토콜 패킷(텍스트 신호)으로 최종 적으로 변환하여 네트워크로 내보내는 역할을 합니다.