- Tomcat 서버가 시작하면서 Servlet Container를 초기화한다. Servlet Container는 Servlet을 라이프 사이클에 따라 생성 및 관리하는 객체이다. 또한 사용자 요청과 Servlet을 매핑해주고, 세션을 관리하며, 동시에 여러 개의 요청을 처리하기 위한 쓰레드 관리 등을 한다.
- Servlet Container는 Servlet Context를 초기화한다. Servlet Context는 각 Servlet과 Servlet Container가 상호 작용 하기 위한 인터페이스이며 웹 애플리케이션 전체가 공유하는 환경을 말한다. 웹 애플리케이션은 하나의 Servlet Context만 가지며, Servlet Context는 웹 애플리케이션이 종료될 때까지 살아있다.
@WebListener로 등록된ServletContextListener를 구현하고 있는ContextLoaderListener가 실행된다. Listener 객체는 이벤트 발생 시 실행되는 객체인데,ServletContextListener는 Servlet Context가 초기화되고 파괴될 때 실행되는 메소드를 정의하기 위한 인터페이스이다. Servlet Context가 생성되면contextInitialized()가 실행되고, Servlet Context가 파괴되면contextDestroyed()가 실행된다.ContextLoaderListener.contextInitialized()는jwp.sql을 실행시켜 데이터베이스를 초기화하고,@Component가 달린 클래스들을 찾아 Servlet Context에 등록시킨다.DispatcherServlet이 초기화된다.DispatcherServlet에는@WebServlet(..., urlPatterns = "/", loadOnStartup = 1)가 달려 있는데,loadOnStartup = 1인 경우 웹 애플리케이션이 시작하자마자 해당 Servlet을 Servlet Container에 로드한다.DispatcherServlet은 프론트 컨트롤러로 서버로 들어오는 모든 요청은 해당 Servlet으로 가게 된다.DispatcherServlet은getHandler()를 통해 요청에 따른 알맞은 핸들러를 찾는데, 이를 위해DispatcherServlet초기화 시HandlerMapping객체를 초기화 시킨다.HandlerMapping의 구현체에는RequestMappingHandlerMapping이 있는데 이는 Servlet Context에 등록된 컴포넌트 중에서@Controller가 달린 컨트롤러를 찾고, 컨트롤러 내 메소드 중에서@RequestMapping이 달린 핸들러들을 찾아((URI, Http Method), Handler)형식으로HashMap에 추가한다.
2. Tomcat 서버를 시작한 후 http://localhost:8080으로 접근시 호출 순서 및 흐름을 설명하라.
DispatcherServlet은 프론트 컨트롤러로 서버에 들어오는 모든 요청을 전달 받는다.HandlerMapping의getHandler()를 통해 요청에 따른 핸들러를 찾는다.getHandlerAdaptor()를 통해 각HandlerAdaptor의supports()를 실행하며getHandler()로 가져온 핸들러에 대한HandlerAdaptor를 찾아handle()를 통해 핸들러 실행을 위임한다.HandlerAdaptor는 핸들러 실행 전HandlerMethodArgumentResolver로 핸들러의 인자들에 알맞은 값들을 넣어준다. 그리고 핸들러를 실행한 뒤HandlerMethodReturnValueHandler로 반환 타입에 따라 알맞은 처리를 한다.HandlerMethodReturnValueHandler가 존재하는 이유는handle()의 반환 타입이ModelAndView로 고정이지만 핸들러의 실행 결과는String,View,ResponseEntity로 다양하기 때문이다.handleReturnValue()는 인자로 전달 받은ModelAndView를 적절히 조작한다.String인 경우ViewNameMethodReturnValueHandler가 실행된다. 이는 해당 값으로View객체를 생성해ModelAndView에 넣는다.View인 경우ViewMethodReturnValueHandler가 실행된다. 이는 해당View를ModelAndView에 넣는다.ModelAndView인 경우ModelAndViewMethodReturnValueHandler가 실행된다. 이는 해당ModelAndView의 값으로 변경한다.ResponseEntity인 경우ResponseEntityMethodReturnValueHandler가 실행된다. 이는 해당 값에 대해 반환 헤더와 바디 등을 설정한다.
DispatcherServlet은HandlerAdaptor로 부터 반환 받은ModelAndView과render()를 통해 사용자에게 응답을 보낸다.