computer_study

[Spring] 10. 스프링 MVC 프레임워크 동작 방식 본문

스터디/스프링5 프로그래밍 입문

[Spring] 10. 스프링 MVC 프레임워크 동작 방식

knowable 2022. 5. 6. 01:09

1. 스프링 MVC 핵심 구성 요소

스프링 MVC의 핵심 구성 요소

  • <<spring bean>> 표기는 스프링 빈으로 등록해야 하는 것을 의미
  • 색칠된 컨트롤러와 JSP는 개발자가 직접 구현해야 하는 요소
  • DispatcherServlet이 모든 연결을 담당
    • HandlerAdapter를 통해 @Controller, Controller 인터페이스, HttpRequestHandler 인터페이스를 동일한 방식으로 처리할 수 있다.

컨트롤러와 핸들러

  • 컨트롤러
    • 요청을 실제로 처리하는 부분
  • 핸들러
    • 웹 요청을 실제로 처리하는 객체
    • @Controller 적용 개체, Controller 인터페이스를 구현한 객체 모두 스프링 MVC입장에서는 핸들러
    • 특정 요청 결로를 처리해주는 핸들러를 찾아주는 객체를 ControllerMapping이 아닌 HandlerMapping이라 부르는 이유
    • 사용 할 핸들러 종류에 따라 HandlerMapping과 HandlerAdapter를 스프링 빈으로 등록해야 한다.
  • DispatcherServlet은 실행 결과를 ModelAndView 타입으로만 받으면 핸들러 객체의 타입은 상관이 없다
    • ModelAndView타입으로 리턴하지 않는 핸들러도 있기에, 핸들러 처리 결과를 HandlerAdapter가 변환해준다

 

2. DispatcherServlet과 스프링 컨테이너

DespatcherServlet은 전달받은 설정 파일을 이용해서 스프링 컨테이너를 생성하는데, 그 안에는 HandlerMapping, HandlerAdapter, 컨트롤러, ViewResolver등의 빈이 있어야 한다. (생성한 컨테이너 안에서 필요한 빈 객체를 구하기 때문에)

때문에 설정 파일에 빈에대한 정의도 포함되어있어야 한다.

 

3. @Controller를 위한 HandlerMapping과 HandlerAdapter

@EnableWebMvc 애노테이션 추가로 HandlerMapping, HandlerAdapter를 빈으로 등록할 수 있다.

(두 가지 뿐만 아니라 다양한 스프링 빈 설정을 추가해준다.)

  • RequestMappingHandlerMapping
    • @Controller 애노테이션이 적용된 객체의 요청 매핑 애노테이션 (@GetMapping)값을 이용해서 웹 브라우저의 요청을 처리할 컨트롤 빈을 찾는다.
  • RequestMappingHandlerAdapter
    • 컨트롤러의 메서드를 실행하고 그 결과를 ModelAndView 객체로 변환해서 DispatcherServlet에 리턴한다.

 

4. WebMvcConfigurer 인터페이스와 설정

@EnableWebMvc 애노테이션은

  • @Controller 애노테이션을 붙인 컨트롤러를 위한 설정을 생성한다.
  • WebMvcConfigurer타입의 빈을 이용해서 MVC 설정을 추가로 생성한다.

 

5. JSP를 위한 ViewResolver

configureViewResolvers 메서드

  • WebMvcConfigurer 인터페이스에 정의
  • ViewResolverRegistry타입의 registry 파라미터를 갖는다.
  • ViewResolverRegisrty#jsp() 메서드를 사용하면 JSP를 위한 ViewResolver를 설정할 수 있다.

DispatcherServlet은 컨트롤러의 실행 결과를 HandlerAdapter를 통해 ModelAndView형식으로 받기에, Model에 담긴 값은 View 객체에 Map 형식으로 전달된다.

model.addAttribute("greeting". "안녕하세요, " + name);
// 위와 같다면, DispatcherServlet은 greeting키를 갖는 Map객체를 View객체에 전달한다.
// 이후 InternalResourceView는 Map객체에 담겨있는 키 값을 request의 속성에 저장한다.
// 이후 JSP를 실행하기에 Model속성이 request객체 속성으로 JSP에 전달되고 다음과 같이 사용이 가능해진다.
인사말 : ${greeting}

 

6. 디폴트 핸들러와 HandlerMapping의 우선순위

웹 브라우저의 요청이 들어왔을 때, DispatcherServlet의 요청 처리 순서

(Request MappingHandlerMapping의 우선순위가 SimpleUrlHandlerMapping보다 높기에 아래처럼 처리)

  • RequestMappingHandlerMapping을 사용해서 요청을 처리할 핸들러 검색
    • 존재하면 해당 컨트롤러를 이용해 요청 처리
  • 존재하지 않으면, SimpleUrlHandlerMapping을 사용해서 요청을 처리할 핸들러를 검색

 

RequestMappingHandlerMapping

  • @Controller 애노테이션을 적용한 빈 객체가 처리할 수 있는 요청 경로만 대응 가능
  • @GetMapping("/hello")라면 "/index.html", "/css/bootstrap.css"등은 찾을 수 없다

configureDefaultServletHandlerConfigure#enable()

"/index.html", "/css/bootstrap.css"등의 경로를 찾기 위한 메서드. 아래 두 객체를 추가한다.

우선순위가 가장 낮기에, 별도 설정이 없는 모든 요청 경로를 디폴트 서블릿이 처리한다.

  • DefaultServletHttpRequestHandler
    • 클라이언트의 모든 요정을 WAS가 제공하는 디폴트 서블릿에 전달
  • SimpleUrlHandlerMapping
    • 모든 경로를 DefaultServletHttp RequestHandler를 이용해서 처리하도록 설정.

 

7. 직접 설정 예

@EnableWebMvc 애노테이션을 사용하지 않아도 스프링 MVC를 사용할 수 있지만 설정해야 될 빈이 많아진다.

8. 정리

Comments