스프링 서버 동작 방식
클라이언트의 요청이 들어오면 서블릿이 이를 처리하는데, 서블릿은 서블릿 컨테이너가 관리한다.
톰캣이 서블릿 컨테이너의 역할과 WAS의 역할을 담당한다
서블릿은 클라이언트의 요청을 처리하고, 결과를 반환하는 자바의 웹 프로그래밍 기술
서블릿 컨테이너의 특징
- 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기 를 관리한다.
- 서블릿 객체는 싱글톤 패턴으로 관리된다
- 멀티 스레딩을 지원한다.

- 클라이언트 요청이 들어오면 서블릿 컨테이너는 Dispatcher Servlet 으로 이를 전달.
- Dispatcher Servlet은 핸들러 매핑을 통해 요청 URI에 매핑된 핸들러를 탐색한다
- 조회한 핸들러(Controller) 를 실행할수 있는 핸들러 어댑터를 조회한다.
- 조회한 핸들러 어댑터로 핸들러를 호출한다
- 핸들러를 실행하여 요청을 처리하고, 응답을 다시 핸들러 어댑터로 반환한다.
- 핸들러 어댑터는 이를 ModelAndView로 가공하여 반환한다.
일반적인 API 서버에서는 @RestController를 사용하므로 View와 ViewResolver를 거치지 않는다. 바로 MessageConvertor를 거쳐서 Json형식으로 변환한 후 ResponseBody로 응답한다.
SSR(Server Side Rendering)을 지원하는 서버에서는 @Controller를 사용할텐데 View Resolver를 찾아서 View의 논리 이름을 물리이름으로 바꾸고, View객체를 반환하고, View를 랜더링하여 클라이언트에 반환하다.
Dispatcher Servlet은 싱글톤 객체로 1개만 존재한다. 즉 톰캣이 멀티 쓰레딩을 지원하여 톰캣에서 동시접근에 대하여 Dispatcher Servlet 에 접근하게 된다.
Dispatcher Servlet은 스프링 개발 철학에 따라 stateless한 구조로 짜여져있기 때문에 동시접근을 해도 문제가 생기지 않는다.
각각의 쓰레드 들은 Dispatcher Servlet에 있는 핸들러 접근 함수의 코드 영역을 읽고 자신의 메모리에서 함수를 호출하여 공유 메모리에 있는 핸들러 매핑을 통해 자신에게 맞는 핸들러를 찾는다.
그리고 핸들러에서 호출 해야할 함수의 코드영역을 읽고 자신의 메모리공간에서 함수를 호출하여 데이터베이스에 접근하거나 로직적인처리를 거친 결과물을 받는다.
따라서 동시접근을 할 때 서로 수정가능한 field가 존재하지 않는 stateless하게 코드를 작성한다면(spring은 애초에 stateless하게 유도) 멀티 쓰레딩을 통해 동시 다발적인 서비스를 지원할수 있다.
