티스토리 뷰
[ Spring Study ]
스프링에 대해 전반적인 구조 및 흐름에 대해서 몰랐던 부분이 너무나 많다는 걸 깨닫게 되는 순간..
한번 쯤 어디선가 읽어봤던 내용들에 대해 개념을 제대로 알고자 스프링에 대해 처음부터 공부한다.
경보 속도로 공부해보자 ! ! !
.
.
한번 쯤 DispatcherServlet 에 대해 들어 본 적이 있으며, 유명한 Spring Request 처리 방식에 대한 그림도 본 적이 있다.
하지만 여러 번 보고 듣는다 한들 전부 뇌리에 스쳐 지나갔다.
지금이라도 Spring 에서 사용자의 요청을 어떻게 처리하는지에 대해서 자세히 알아봐야 하지 않을까 ?
.
.
DispatcherServlet 은 spring 기반 웹 애플리케이션의 Front Controller 역할을 한다.
🤚 Front Controller 는 무엇이길래 ? Front Controller 부터 짚고 넘어가보자.
Front Controller 는 소프트웨어 디자인 패턴으로 웹 애플리케이션으로 요청이 들어오면 *서블릿 하나로 모든 요청을 받는다.
프론트 컨트롤러는 클라이언트의 요청을 받은 후, 해당 요청은 어느 컨트롤러가 처리해야 되는지를 결정한다.
프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 된다.
(* 프론트 컨트롤러를 사용하지 않았을 당시에는, 요청 별로 서블릿을 생성하였다.)
.
.
DispatcherServlet 으로 넘어와서..
DispatcherServlet 이 프론트 컨트롤러 역할을 할 수 있는 건, 프론트 컨트롤러 패턴으로 구현되어 있기 때문이다.
HTTP Request 를 처리하고 위임하고, 핸들러 · 컨트롤러 · 응답 객체로 구성된 스프링 애플리케이션 내에 구현된 HandlerAdapter 인터페이스에 설정에 따라 요청을 처리한다.
DispatcherServlet 이 동작하는 흐름을 확인해보자.
1) HTTP 요청 : DispatcherServlet 이 request 를 받는다.
2) 핸들러 조회 : DispatcherServlet 은 *HandlerMapping 을 통해 요청과 관련된 핸들러(Controller) 를 조회한다.
즉, 어떤 컨트롤러가 요청을 처리할 것인지를 결정한다.
3) 핸들러 어댑터 조회 : DispatcherServlet 은 *HandlerAdapter 를 통해 핸들러(Controller)를 실행할 수 있는 핸들러 어댑터를 조회한다.
4) 핸들러 어댑터 실행 : HandlerAdapter 는 핸들러(Controller) 를 호출한다.
즉, HandlerMapping 을 통해 찾은 핸들러를 직접 실행한다.
5) ModelAndView 반환 : 핸들러(Controller)는 비즈니스 로직을 처리한 후, Model 에 결과 값을 담고 HandlerAdapter 에게 view의 논리적인 이름을 반환한다.
6) ViewResolver 호출 : DispatcherServlet 은 *ViewResolver 를 호출하여 뷰의 논리 이름을 물리 이름으로 바꾸고, view 객체를 반환한다.
7) View 반환 : DispatcherServlet 은 view 에게 model을 전달하고 화면 표시(render)를 요청한다.
8) HTML 응답 : model 에 담아있던 데이터를 view 에 보여준다.
DispatcherServlet 핵심 로직 분석
protected void doDispatch(HttpServletRequest request,
HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
// 핸들러 조회
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 핸들러 어댑터 조회 (핸들러를 처리할 수 있는 어댑터)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 핸들러 어댑터 실행
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();
// 뷰 리졸버를 통해 뷰 찾기
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 뷰 렌더링
view.render(mv.getModelInternal(), request, response);
}
참고
스프링 MVC 1편 - 김영한
'Framework > Spring' 카테고리의 다른 글
auto-configuration에 대하여 (0) | 2024.10.23 |
---|---|
[Web] Servlet 과 Servlet Container (0) | 2022.12.26 |
[Spring] 순환 참조 (0) | 2022.12.13 |
[JPA] N + 1 문제 (0) | 2022.12.05 |
[JPA] 즉시로딩과 지연로딩 (0) | 2022.11.14 |
- Total
- Today
- Yesterday
- 티스토리챌린지
- fail-fast
- Sticky Session
- Red-Black Tree
- HashSet
- 오블완
- 로드 밸런서
- Load Balancer
- syncronized
- 자동구성
- 정적변수
- 고정 세션
- object
- fail-safe
- Security
- 다중화
- HashMap
- spring boot
- JPA
- nginx
- nosql
- 추상클래스
- java
- Spring
- 인스턴스변수
- 인터페이스
- Caching
- Hash
- @conditional
- AutoConfiguration
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |