MVC 패턴

FrontController 패턴
클라이언트에서 요청시 Servlet으로 요청되게 되고,
각 컨트롤러에서 Servlet을 모두 처리하는 로직을 구현하게 되면 비효율적이다.
그에 따라, Front Controller에서 Servlet 하나로 클라이언트의 요청을 받고, 그에 맞는 하위 컨트롤러를 호출해주는 패턴이다.

viewResolver: 컨트롤러가 반환한 논리 뷰 이름을 실제 물리 뷰 경로로 변경한다. 구체적으로는 실제 물리 경로가 있는 View 객체를 반환한다.
Adapter 패턴
개발자에 따라 여러 가지 패턴으로 컨트롤러를 구현할 수 있다.
이 경우, 패턴별로 컨트롤러가 뷰를 위해 데이터를 넘기는 방식은 다를 수 있다.
그에 따라 어댑터를 사용하여
- 컨트롤러별로 뷰에 데이터를 넘기는 방식을 정형화하고
- FrontController에서
- 같은 패턴의 컨트롤러들은 하나의 어뎁터를 통해 뷰를 호출하게 하며
- HandlerMapping을 통해 URI와 매칭되는 적합한 하위 컨트롤러를 찾고
- HandlerAdapter를 통해 하위 컨트롤러를 사용하기 위해 적합한 Adapter를 호출하고
- 호출된 Adapter를 통해 ModelView를 만들 수 있다.
Spring MVC 구조

HandlerMapping
URI로 컨트롤러를 찾는 것
HandlerAdapter
핸들러 매핑에서 찾은 핸들러를 실행할 수 있는 어댑터
스프링에서 자동 등록하는 핸들러 매핑과 어댑터
HandlerMapping
0순위: RequestMappingHandlerMapping
- Annotation 기반 컨트롤러인 @RequestMapping에서 사용
1순위: BeanNameUrlHandlerMapping
HandlerAdapter
0순위: RequestMappingHandlerAdapter
- Annotation 기반 컨트롤러인 @RequestMapping에서 사용
1순위: HttpRequestHandlerAdapter
- HttpRequestHandler 처리. HttpServlet 방식과 거의 비슷
2순위: SimpleControllerHandlerAdapter
- Controller 인터페이스(과거에 사용된 것으로, 애노테이션 타입을 지칭하는 것이 아님.) 처리
Spring에서 Handler Mapping, Adapter, ViewResolver 동작 간단 로직
- 핸들러 매핑으로 핸들러 조회
- 핸들러 어댑터 조회
- HandlerAdapter.supports()를 순차 호출
- 핸들러 어댑터 실행
- 핸들러 어댑터에서 얻은 논리 뷰 이름으로 ViewResolver 호출
- BeanNameViewResolver에서 먼저 찾고, InternalResourceViewResolver에서 찾는다.
- InternalResourceView를 반환한다.
- InternalResourceView는 JSP처럼 forward()를 호출해서 처리할 수 있을 때 사용한다.
- view.render() 호출됨
- InternalResourceView는 forward()를 호출해서 JSP 실행
Spring MVC와 MVC패턴과의 용어 매핑
- FrontController = DispatcherServlet
- handlerMappingMap = HandlerMapping
- MyHandlerAdapter = HandlerAdapter
- Adapter Interface로, 인터페이스의 구현체들은 각 컨트롤러 그룹별 ModelView 생성 로직이 구현되어있다. (handle())
- ModelView = ModelAndView
- view의 논리적인 이름과, 필요한 데이터들이 담긴 Map이 저장된 곳
- viewResolver = ViewResolver
- view의 논리적인 이름을 실제 물리 경로가 있는 View객체로 변환한다.
- MyView = View
- View Path와, HttpServletRequest/Response, 컨트롤러에서 추가된 데이터들이 저장된 Map을 가진 객체이다.
- 해당 객체에서 Controller -> View로 넘어가기 위해 dispatcher.forward를 호출하게 된다.
JSP를 제외한 다른 뷰 템플릿들은 forward() 과정 없이 바로 렌더링 된다.