2022. 9. 2. 02:02ㆍSpring
스프링 구조를 그림으로 간단히 보여주는 이미지이다.
모든 요청은 일단 FrontController인 `DispatcherServlet`에서 시작된다.
요청을 처리하기 위해서는 `DispatcherServlet`이 미리 담아두어야 할 값들에 대해서, 실행 로직에 대해서 스프링의 코드로 좀 더 자세히 봤다.
* 요청의 시작
먼저 서블릿이 호출되면 `HttpServlet`이 제공하는 `service()`가 호출된다.
스프링MVC에서 `HttpServlet`는 `DispatchServlet`이 상속받고 있는 `FrameworkServlet`에서 `service()`를 오버라이드 해두었고 `FrameworkServlet.service()`를 시작으로 `DispatchServlet`의 `doDispatch()` 메소드를 실행하며 여기에 핵심 로직이 다 들어있다.
DispatcherServlet 초기화 단계에서 스프링 컨테이너를 매개변수로 받아서 initStrategies 메소드를 실행하게 된다.
여기서 요청에 필요한 여러 값들을 초기화해둔다.
* HandlerMappings
그 중에서 initHandlerMappings이라는 메소드를 실행한다. 이 메소드는 들어온 요청을 처리할 수 있는 핸들러들을 List에 담아두는 역할을 한다.
HandlerMapping 인터페이스를 구현한 모든 class를 빈으로 등록하고 matchingBeans에 넣은 뒤 value값들을 뽑아 HandlerMappings(List)에 넣는다.
matchingBeans Map에서 value값의 타입인 HandlerMapping는 요청과 핸들러 개체 간의 매핑을 정의하는 인터페이스이다.
* HandlerAdapters
여러타입의 요청을 받고 응답을 주기 위해서는 DispatcherServlet과 핸들러(컨트롤러) 사이에 타입을 맞춰줄 단계를 하나 두어야한다. 마치 110v를 쓰기위해 중간에 어탭터를 사용해 맞추는것처럼!
마찬가지로 initHandlerAdapters 메소드를 통해 핸들러 어댑터를 초기화한다.
handlerAdapters에는 이런 HandlerAdapter들이 담겨있다.
HandlerAdapter타입도 인터페이스로 구현되어 있다.
이 인터페이스에는
- 매개변수로 들어온 핸들러의 인스턴스를 확인해 해당 HandlerAdapter가 지원할 수 있는지 여부를 boolean 타입으로 반환하는 supports메소드와
- request, response객채와 핸들러(컨드롤러)를 매개변수로 받아 핸들러의 로직을 실행시킬 수 있는 handle 메소드를 담고 있다.
- 컨트롤러를 실행하면 ModelAndView 타입으로 동일하게 반환하여 DispatcherServlet에서 사용할 수 있게 한다.
- 리턴 타입(ModelAndView)을 맞춘덕분에 어떤 타입의 요청과 응답에도 DispatcherServlet에서 동일한 로직을 실행 할 수 있게된다. = (어떤 타입이던지 처리할 수 있다!!)
이렇게 필요한 핸들러들과 핸들러 어댑터들을 담아놓으면 이후의 요청에 따라 핸들러를 가져오고, 그 핸들러를 실행할 수 있는 핸들러 어댑터를 찾아오게된다.
* 요청에 맞는 핸들러 찾기_getHandler
request객체를 가지고 HandlerMappings에 담겨져있는만큼 for문을 돌며 해당 요청에 맞는 handler를 찾아 반환한다.
* 핸들러를 실행할 수 있는 어댑터 찾기_getHandlerAdapter
그러면 그 handler를 가지고 handler를 실행시킬 수 있는 HandlerAdapter를 찾는다.
HandlerAdapters에서 for문을 돌며
supports를 통해 어댑터 지원 여부를 판단하고 true면 handle 메소드를 실행하며 컨트롤러 로직을 실행한다.
handler를 처리할 수 있는 HandlerAdapter가 없다면 예외를 던진다.
* 핸들러 실행과 동일한 타입 반환
위의 로직에서 요청에 맞는 handlerAdapter를 찾으면 매개변수로 받은 핸들러와 함께 handle메소드를 실행해 컨트롤러 로직을 실행한다.
그리고 ModelAndView 를 리턴값으로 반환 한다.
* 이후 로직
ModelAndView를 가지고 viewResolver를 거치면 View를 반환하게 되는데
View 인터페이스에는
컨트롤러 로직 실행을 마치고 결과값이 담겨있는 model매개변수와 request, response객체를 가지고 최종적으로 요청에 대한 응답이 나가게 하는 render메소드가 있다.
processDispatchResult 속 render 메소드를 통해 최종적으로 요청과 응답에 대한 싸이클이 마무리된다.
'Spring' 카테고리의 다른 글
MVC패턴 이해하기1 (0) | 2022.10.25 |
---|---|
MVC패턴의 등장 (0) | 2022.10.25 |
[Spring] - 414 request-uri too large (0) | 2021.03.22 |
[Srping] 전자정부프레임워크 - mariadb 연결 (0) | 2021.03.16 |
[Spring] @Scheduled 스프링 스케쥴러 (0) | 2021.03.10 |