스프링 MVC -3

김성훈·2022년 2월 26일
0

스프링 인프런강의

목록 보기
9/13
post-thumbnail

<출처>

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 /인프런 강의/ 김영한

5.스프링 MVC- 구조 이해 - 스프링 MVC 전체 구조
5.스프링 MVC- 구조 이해 - 핸들러 매핑과 핸들러 어댑터
5.스프링 MVC- 구조 이해 - 뷰 리졸버

관련코드
https://github.com/sunghoonking/spring-mvc-inflearn/tree/main/src/main/java/hello/servlet/web

직접 만든 프레임워크 스프링 MVC 비교

  • FrontController -> DispatcherServlet
  • handlerMappingMap -> HandlerMapping
  • MyHandlerAdapter -> HandlerAdapter
  • ModelView -> ModelAndView
  • viewResolver -> ViewResolver
  • MyView -> View

DispatcherServlet

가장 앞단에서 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller)

protected void doDispatch(HttpServletRequest request, HttpServletResponse 
response) throws Exception {

HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;

// 1. 핸들러 조회
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}

// 2. 핸들러 어댑터 조회 - 핸들러를 처리할 수 있는 어댑터
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 3. 핸들러 어댑터 실행 -> 4. 핸들러 어댑터를 통해 핸들러 실행 -> 5. ModelAndView 반환
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

processDispatchResult(processedRequest, response, mappedHandler, mv,
dispatchException);
}

private void processDispatchResult(HttpServletRequest request,
HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView 
mv, Exception exception) throws Exception {

// 뷰 렌더링 호출
render(mv, request, response);
}

protected void render(ModelAndView mv, HttpServletRequest request,
HttpServletResponse response) throws Exception {

View view;
String viewName = mv.getViewName();

// 6. 뷰 리졸버를 통해서 뷰 찾기, 7. View 반환
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);

// 8. 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}

SpringMVC 구조 및 동작 순서

인터페이스 살펴보기

  • 스프링 MVC의 큰 강점은 DispatcherServlet 코드의 변경 없이, 원하는 기능을 변경하거나 확장할 수
    있다는 점이다. 지금까지 설명한 대부분을 확장 가능할 수 있게 인터페이스로 제공한다.
  • 이 인터페이스들만 구현해서 DispatcherServlet 에 등록하면 여러분만의 컨트롤러를 만들 수도 있다

핸들러 매핑과 핸들러 어댑터

핸들러 매핑
Dispatcher Servlet이 요청 URI가 어떤 핸들러와 매핑되는지 찾는 과정이다. 핸들러 매핑은 결국 요청과 알맞는 핸들러 객체를 Dispatcher Servlet에 리턴한다.

핸들러 어댑터
HandlerMapping을 통해 찾은 컨트롤러를 직접 실행하는 기능을 수행

스프링도 처음에는 이런 딱딱한 형식의 컨트롤러를 제공했다.

HandlerMapping
0 = RequestMappingHandlerMapping:
애노테이션 기반의 컨트롤러인 @RequestMapping에서 사용

1 = BeanNameUrlHandlerMapping :
스프링 빈의 이름으로 핸들러를 찾는다.

HandlerAdapter
0 = RequestMappingHandlerAdapter :
애노테이션 기반의 컨트롤러텍스트인 @RequestMapping에서 사용

1 = HttpRequestHandlerAdapter :
HttpRequestHandler 처리

2 = SimpleControllerHandlerAdapter :
Controller 인터페이스(애노테이션X, 과거에 사용) 처리

1. 핸들러 매핑으로 핸들러 조회

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

2. 핸들러 어댑터 조회

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

3. 핸들러 어댑터 실행

    1. 디스패처 서블릿이 조회한 SimpleControllerHandlerAdapter 를 실행하면서 핸들러 정보도 함께 넘겨준다.
    1. SimpleControllerHandlerAdapter 는 핸들러인 OldController 를 내부에서 실행하고, 그 결과를반환한다.

정리 - OldController 핸들러매핑, 어댑터
OldController 를 실행하면서 사용된 객체는 다음과 같다.
HandlerMapping = BeanNameUrlHandlerMapping
HandlerAdapter = SimpleControllerHandlerAdapter

ViewResolver

스프링 부트가 자동 등록하는 뷰 리졸버
1 = BeanNameViewResolver :
빈 이름으로 뷰를 찾아서 반환한다. (예: 엑셀 파일 생성 기능에 사용)

2 = InternalResourceViewResolver :
JSP를 처리할 수 있는 뷰를 반환한다

1. 핸들러 어댑터 호출
핸들러 어댑터를 통해 new-form 이라는 논리 뷰 이름을 획득한다.

2. ViewResolver 호출
new-form 이라는 뷰 이름으로 viewResolver를 순서대로 호출한다.
BeanNameViewResolvernew-form 이라는 이름의 스프링 빈으로 등록된 뷰를 찾아야 하는데 없다.
InternalResourceViewResolver 가 호출된다.

3. InternalResourceViewResolver
이 뷰 리졸버는 InternalResourceView 를 반환한다.

4. 뷰 - InternalResourceView
InternalResourceView 는 JSP처럼 포워드 forward() 를 호출해서 처리할 수 있는 경우에 사용한다.

5. view.render()
view.render() 가 호출되고 InternalResourceViewforward() 를 사용해서 JSP를 실행한

profile
"한 명이 걷는 천 걸음 보다 천 명이 함께 걷는 한 걸음이 성공의 시작이고 완성이다"

0개의 댓글

관련 채용 정보