스프링 Web MVC 주요 흐름 정리

선종우·2023년 6월 19일
0

1. DispatcherServlet

  • Spring WEB MVC는 FrontController 패턴을 사용한다. 이때 FrontController역할을 하는 객체가 DispatcherServlet이다.
  • DispatcherServlet은 Servlet을 상속하며 모든 웹 요청에서 가장 먼저 수행된다.
  • 내가 생각하는 Spring Web MVC의 핵심 키워드 로직은 아래와 같다.
    • 핸들러 매핑 : 요청한 URL에 맞는 핸들러(컨트롤러)를 찾는 과정
    • 핸들러 어댑터 : 다양한 형태의 핸들러(컨트롤러)를 일관된 방식으로 FrontController에서 호출할 수 있게 지원하는 객체
    • 핸들러(컨트롤러) : 사용자 요청을 비즈니스 로직으로 연결하는 객체(실제 내가 구현한 controller 코드)
    • 뷰 리졸버 : 컨트롤러가 반환한 view의 논리적인 이름을 실제 경로로 연결하고 view를 템플릿 엔진에 연결하는 객체
    • 인터셉터 : 컨트롤러 수행전/후/완료 후 실행되는 객체
    • 익셉션 핸들러 : controller아래에서 발생한 에러에 대한 처리를 지원하는 객체

2. 추상화된 호출 메소드 순서

|doDispatch()
 --> |mappedHandler = getHandler(processedRequest);
 --> |HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
 --> |mappedHandler.applyPreHandle(processedRequest, response)
 --> |mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
 --> |mappedHandler.applyPostHandle(processedRequest, response, mv);
 --> |processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
      --> |mv = processHandlerException(request, response, handler, exception);
      --> |render(mv, request, response);
      --> |view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
      --> |view.render(mv.getModelInternal(), request, response);
      --> |mappedHandler.triggerAfterCompletion(request, response, null);
  • 메소드 호출 순서를 인터셉터의 수행시점을 이해할 수 있다.
  • applyPostHandle의 경우 controller 수행 간 예외 발생시(ha.handle()) catch문으로 넘어가기 때문에 실행되지 않는다. 반면 afterCompletion의 경우 processDispatchResult()내부 또는 finally에서 실행되기 때문에 예외 발생과 상관없이 무조건 실행된다.

3. HandlerMapping 구조

  • DispatcherServlet에는 아래와 같은 변수가 있다.
private List<HandlerMapping> handlerMappings
  • 해당 변수를 실행 과정에서 디버깅 해보면 {RequestMappingHandlerMapping, BeanNameUrlHandlerMapping, RouterFunctionMapping, SimpleUrlHandlerMapping, WelcomPagehandlerMapping} 이 할당되어 있다.
  • 일반적으로는 HandlerMethod를 쓰게되는데, 이는 RequestMappingHanlerMapping이 처리한다.
    • RequestmappingHandlerMapping : @RequestMapping 컨트롤러 매핑
      -> RequestmappingHandlerMapping이 처리
    • BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러 매핑
      -> SimpleControllerHandlerAdapter가 처리
  • RequestMappingHanlerMapping 내부를 보면 AbstracHandlerMehtodMapping.MappingRegistry mappingRegistry가 선언되어 있고, registry에는 URL과 해당하는 handlerMethod(AbstractHandlerMethodMapping~)가 key:value형태로 등록되어 있다.

0개의 댓글