본문 바로가기
Spring(JAVA Framework)/Spring MVC

SpringMVC 구조

by 걸어가는 신사 2021. 9. 15.

1. 동작 순서

(1) Handler 조회 : HandlerMapping을 통해 요청 URL에 매핑된 Handler(Controller)를 조회한다.

(2) HandlerAdapter 조회 : Handler를 실행할 수 있는 HandlerAdapter를 조회한다.

(3) HandlerAdapter 실행 : Handler adapter를 실행한다.

(4) Handler 실행 : HandlerAdapter가 실제 Handler를 실행한다. 

(5) ModelAndView 반환 : HandlerAdapter는 Handler가 반환하는 정보를 ModelAndView로 변환해서 변환한다.

(6) ViewResolver 호출 : ViewResolver를 찾고 실행한다.

(7) View 반환 : ViewResolver는 View의 논리 이름을 물리 이름으로 바꾸고 렌더링 역할의 뷰 객체를 반환한다.

(8) View 렌더링 : View를 통해서 View를 렌더링 한다.

 

주요 인터페이스 목록
(1) HandlerMapping : org.springframework.web.servlet.HandlerMapping
(2) HandlerAdapter : org.springframework.web.servlet.HandlerAdapter
(3) ViewResolver : org.springframework.web.servlet.ViewResolver
(4) View : org.springframework.web.servlet.View

 

2. HandlerMapping과 HandlerAdapter

(1) 스프링 부트가 자동 등록하는 HandlerMapping과 HandlerAdapter

HandlerMapping
0 = RequestMappingHandlerMapping : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러를 찾는다.
HandlerAdapter
0 = RequestMappingHandlerAdapter : 애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용
1 = HttpRequestHandlerAdapter : HttpRequestHandler 처리
2 = SimpleControllerHandlerAdapter : Controller 인터페이스(애노테이션 X, 과거에 사용) 처리

(2) HandlerMapping, HandlerAdapter 동작 방식

package hello.servlet.web.springmvc.old;

import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component("/springmvc/request-handler")
public class MyHttpRequestHandler implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("MyHttpRequestHandler.handleRequest");
    }
}

(i) HandlerMapping으로 Handler 조회

  • HandlerMapping을 순서대로 실행해서, Handler를 찾는다.
  • 이 경우 빈 이름으로 Handler를 찾아야 하기 때문에 이름 그대로 빈 이름으로 Handler를 찾아주는 BeanNameUrlHandlerMapping 가 실행에 성공하고 핸들러인 MyHttpRequestHandler를 반환한다.

(ii) HandlerAdapter 조회

  • HandlerAdapter의 supports()를 순서대로 호출한다.
  • HttpRequestHandlerAdapter 가 HttpRequestHandler 인터페이스를 지원하므로 대상이 된다.

(iii) HandlerAdapter 실행

  • DispatcherServlet이 조회한 HttpRequestHandlerAdapter를 실행하면서 핸들러 정보도 함께 넘겨준다.
  • HttpRequestHandlerAdapter는 핸들러인 MyHttpRequestHandler를 내부에서 실행하고, 그 결과를 반환한다.

 

3. ViewResolver

  • 스프링 부트는 InternalResourceViewResolver라는 ViewResolver를 자동으로 등록한다. 이때 application.properties 에 등록한 spring.mvc.view.prefix , spring.mvc.view.suffix 설정 정보를 사용해서 등록한다.

(1) 스프링 부트가 자동 등록하는 ViewResolver

1 = BeanNameViewResolver : 빈 이름으로 뷰를 찾아서 반환한다. (예: 엑셀 파일 생성 기능에 사용)
2 = InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환한다.

(2) ViewResolver 동작 방식

package hello.servlet.web.springmvc.old;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component("/springmvc/old-controller")
public class OldController implements Controller {
     @Override
     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
         System.out.println("OldController.handleRequest");
         return new ModelAndView("new-form");
     }
}
//application.properties
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
  • HandlerAdapter 호출
    • HandlerAdapter를 통해 "new-form" 논리 뷰 이름을 얻는다.
  • ViewResolver 호출
    • 뷰 이름으로 ViewResolver를 순서대로 후출한다.
    • BeanNameViewResolver는 뷰 이름의 스프링 빈으로 등록된 뷰를 찾아야 하는데 없다.
    • InternalResourceViewResolver가 호출된다.
  • InternalResourceViewResolver
    • InternalResourceView를 반환한다.
  • 뷰-InternalResourceView
    • InternalResourceView는 JSP처럼 포워드 forward()를 호출해서 처리할 수 있는 경우에 사용한다.
  • view.render()
    • view.render()가 호출되고 InternalResourceView는 forward()를 사용해서 JSP 실행한다.

 

반응형

'Spring(JAVA Framework) > Spring MVC' 카테고리의 다른 글

HTTP Request - (1) (feat. Request Parameter)  (0) 2021.09.16
@RequestMapping  (0) 2021.09.15
HTTP Response 데이터  (0) 2021.08.29
HTTP Request 데이터  (0) 2021.08.29
Servlet 환경 세팅과 등록  (0) 2021.08.28

댓글