Spring MVC - FrontController 패턴과 Adapter 패턴

Hansu Kim·2022년 5월 8일
0

Spring MVC

목록 보기
6/6

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 동작 간단 로직

  1. 핸들러 매핑으로 핸들러 조회
  2. 핸들러 어댑터 조회
    • HandlerAdapter.supports()를 순차 호출
  3. 핸들러 어댑터 실행
  4. 핸들러 어댑터에서 얻은 논리 뷰 이름으로 ViewResolver 호출
    • BeanNameViewResolver에서 먼저 찾고, InternalResourceViewResolver에서 찾는다.
      • InternalResourceView를 반환한다.
      • InternalResourceView는 JSP처럼 forward()를 호출해서 처리할 수 있을 때 사용한다.
  5. view.render() 호출됨
  • InternalResourceView는 forward()를 호출해서 JSP 실행

Spring MVC와 MVC패턴과의 용어 매핑

  • FrontController = DispatcherServlet
  • handlerMappingMap = HandlerMapping
    • URI와 컨트롤러가 매핑된 맵
  • 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() 과정 없이 바로 렌더링 된다.

0개의 댓글