* 스프링 입문 = window, 스프링 MVC 1편 = Mac 으로 진행합니다
* 진도 : 섹션5 - (1) ~ (3)
* : 자바 클래스명, : 코드, : 단축키
1. 스프링 MVC 전체 구조
1) 직접 만든 프레임워크(= 섹션 4) 스프링 MVC 비교
- FrontController → DispatcherServlet
- handlerMappingMap → HandlerMapping
- MyHandlerAdapter → HandlerAdapter
- ModelView → ModelAndView
- viewResolver → ViewResolver
- MyView → View
2) DispatcherServlet 구조
- 스프링 MVC의 프론트 컨트롤러 = 디스패처 서블릿(DispatcherServlet)
- DispacherServlet 도 부모 클래스에서 HttpServlet 을 상속 받아서 사용하고, 서블릿으로 동작
(DispatcherServlet → FrameworkServlet → HttpServletBean → HttpServlet) - 서블릿이 호출되면 HttpServlet 이 제공하는 serivce() 호출 (핵심 코드 DispacherServlet.doDispatch 참고)
더보기
// 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());
//6. 뷰 리졸버를 통해서 뷰 찾기,7.View 반환
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 8. 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}
3) 동작 순서
- 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
- 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
- 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
- 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
- ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
- viewResolver 호출: 뷰 리졸버를 찾고 실행한다.
- View반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로바꾸고, 렌더링 역할을 담당하는 뷰객체를 반환한다.
- 뷰렌더링: 뷰를 통해서 뷰를 렌더링한다.
2. 핸들러 매핑과 핸들러 어댑터
<OldController>
- 스프링 빈의 이름으로 핸들러를 찾을 수 있는 핸들러 매핑이 필요하다.
-
@Component("/springmvc/old-controller") = 빈의 이름으로 URL을 매핑
더보기
@Component("/springmvc/old-controller")
public class OldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("OldController");
return null;
}
}
- 핸들러 매핑으로 핸들러 조회
- HandlerMapping 순서대로 실행해서 핸들러 찾기
- 빈 이름으로 핸들러 찾는 BeanNameUrlHandlerMapping 실행
- HandlerMapping 순서대로 실행해서 핸들러 찾기
- 핸들러 어댑터 조회
- HandlerAdapter의 supports() 순서대로 실행해서 핸들러 찾기
- SimpleControllerHandlerAdapter가 Controller 인터페이스를 지원하므로 대상이 된다
- HandlerAdapter의 supports() 순서대로 실행해서 핸들러 찾기
- 핸들러 어댑터 실행
- 디스패처 서블릿이 조회한 SimpleControllerHandlerAdapter를 실행 + 핸들러 정보 넘기기
- SimpleControllerHandlerAdapter는 핸들러인 OldController를 내부에서 실행하고 결과 반환
- 디스패처 서블릿이 조회한 SimpleControllerHandlerAdapter를 실행 + 핸들러 정보 넘기기
<HttpRequestHandler>
- 서블릿과 가장 유사한 핸들러
더보기
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("MyHttpRequestHandler");
}
}
- 핸들러 매핑으로 핸들러 조회
- HandlerMapping 순서대로 실행해서 핸들러 찾기
- 빈 이름으로 핸들러 찾는 BeanNameUrlHandlerMapping 실행에 성공하고 핸들러인 MyHttpRequestHandler 반환
- HandlerMapping 순서대로 실행해서 핸들러 찾기
- 핸들러 어댑터 조회
- HandlerAdapter의 supports() 순서대로 실행해서 핸들러 찾기
- HttpRequestHandlerAdapter가 HttpRequestHandler 인터페이스를 지원하므로 대상이 된다
- HandlerAdapter의 supports() 순서대로 실행해서 핸들러 찾기
- 핸들러 어댑터 실행
- 디스패처 서블릿이 조회한HttpRequestHandlerAdapter 를 실행 + 핸들러 정보 넘기기
- HttpRequestHandlerAdapter는 핸들러인 MyHttpRequestHandler를 내부에서 실행하고 결과 반환
- 디스패처 서블릿이 조회한HttpRequestHandlerAdapter 를 실행 + 핸들러 정보 넘기기
< OldController - View >
- OldController 실행하면 화면이 아무것도 뜨지 않는다 → View 설정 필요
- application.properties 에 코드 추가
더보기
[ src - java - hello .servlet - web -springmvc - old - OldController]
@Component("/springmvc/old-controller")
public class OldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("OldController");
return new ModelAndView("new-form");
}
}
뷰 리졸버 호출 [ src - main - resources - application.properties ]
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
- 핸들러 어댑터 호출
- 핸들러 어댑터를 통해 "new-form" (뷰 논리이름) 획득
- ViewResolver 호출
- "new-form"이라는 뷰 이름으로 viewResolver 순서대로 호출
- 빈 이름으로 찾는 BeanNameViewResolver로 등록된 뷰 찾기
- 없다면 InternalResourceViewResolver로 호출하고 InternalResourceView 를 반환
- "new-form"이라는 뷰 이름으로 viewResolver 순서대로 호출
- 뷰 InternalResourceView
- InternalResourceView는 JSP처럼 forward()를 호출해서 처리할 수 있는 경우에 사용한다
- InternalResourceView는 JSP처럼 forward()를 호출해서 처리할 수 있는 경우에 사용한다
- 렌더링 view.render()
- view.render() 호출되고 InternalResourceView는 forward()를 사용해서 JSP 실행
'Spring > 스프링 MVC' 카테고리의 다른 글
[스프링 MVC 1편] 6 - (1) 스프링 MVC 프로젝트 생성 & 로깅 (1) | 2023.11.22 |
---|---|
[스프링 MVC 1편] 5 - (2) 스프링 MVC (2) | 2023.11.17 |
[스프링 MVC 1편] 4 - (5) 프론트 컨트롤러 - v5 (1) | 2023.11.13 |
[스프링 MVC 1편] 4 - (4) 프론트 컨트롤러 - v4 (0) | 2023.11.10 |
[스프링 MVC 1편] 4 - (3) 프론트 컨트롤러 - v3 (0) | 2023.11.10 |