반응형
이전 글에서 프론트 컨트롤러 패턴으로 프레임 워크를 구현해봤는데
그 구조는 스프링 MVC와 동일하다.
직접 만든 프레임워크와 스프링 MVC 비교
- FrontController → DispatcherServlet
- handlerMappingMap → HandlerMapping
(inerterface) - MyHandlerAdapter → HandlerAdapter
- ModelView → ModelAndView
- viewResolver → ViewResolver
(interface) - MyView → View
(인터페이스)
디스패쳐 서블릿(DispatchServlet) 구조
지금까지 위의 내용은 스프링 MVC를 아주 간단하게 만든 프레임워크이다.
즉, 스프링에서 DispatcherServlet이 프론트 컨트롤러이며, 가장 핵심이 된다.
DispatcherServlet 서블릿 등록
DispatcherServler도 부모 클래스에서HttpServlet을 상속 받아서 사용하고, 서블릿으로 동작한다.- DispatcherServlet → FrameworkServlet → HttpServletBean → HttpServlet
- 스프링 부트는
DispatcherServlet을 서블릿으로 자동으로 등록하면서 모든 경로(urlPattern=”/”)에 대해 매핑한다.- 참고 : 더 자세한 경로가 우선 순위가 높음
요청 흐름
- 서블릿이 호출되면
HttpServlert이 제공하는service()가 호출된다. - 스프링 MVC는
DispatcherServlet의 부모인FrameworkServelt에서service()를 오버라이드 함. FrameworkServlet.service()를 시작으로 여러 메서드가 호출되면서DispatcherServlet.doDispatcher()가 호출 됨.

doDistpatcherServlet()
DispatcherServlet에서 가장 중요한 메서드이다. 아주 간단하게 코드를 요약해서 살펴 보자.
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) {
noHandleFound(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);
}
동작 순서
- 핸들러 조회
→ 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다. - 핸들러 어댑터 조회
→ 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다. - 핸들러 어댑터 실행
→ 핸들러 어댑터를 실행한다. - 핸들러 실행
→ 핸들러 어댑터가 실제 핸들러를 실행한다. - ModelAndView 반환
→ 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다. - viewResolver 호출
→ 뷰 리졸버를 찾고 실행한다.
→ JSP는InternalResourceIvewResolver가 자동 등록되고, 사용된다. - View 반환
→ 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담항하는 뷰 객체를 반환한다.
→ JSP의 경우InternalResourceIvew(JstlView)를 반환 하는데,
내부에forward()로직이 있다. - 뷰 렌더링
→ 뷰를 통해서 뷰를 렌더링 한다.
스프링 MVC의 강점
- DispatcherServlet 코드의 변경 없이, 원하는 기능을 변경하거나 확장할 수 있다.
그렇기 때문에 대부분 인터페이스로 제공된다. - 이 인터페이스만 구현해서 DispatcherServlet에 등록하면 커스텀 컨트롤러도 만들 수 있는 것이다.
정리
너무 깊게 들어갈 필요는 없고 이렇게 큰 그림만 알고 있으면 된다.
이미 스프링에 다 구현이 되어 있기 때문이고, 문제 해결에 도움이 되고, 확정 포인트를 알 수 있을 것이다.
모든 것이 그렇듯.
반응형
'Spring' 카테고리의 다른 글
| 스프링의 뷰 리졸버 (0) | 2022.01.24 |
|---|---|
| 스프링의 핸들러 매핑과 어댑터 (0) | 2022.01.24 |
| 프론트 컨트롤러 패턴 (0) | 2022.01.24 |
| 서블릿, JSP, MVC 패턴의 차이 (0) | 2022.01.24 |
| 서블릿과 톰캣의 관계 (0) | 2022.01.24 |