Tomcat 과 Spring MVC의 동작 과정

개뉸·2022년 10월 8일
3

Tomcat
로컬에서 스프링으로 코드를 짜고 실행했을때 로그에서 본적이 아주 많이 있었다.
spring 내부적으로 돌아가는 기능들 중에 하나겠거니 하고 넘어갔지만 생각보다 대단한 녀석이다.

톰켓을 이해하려면 우선 http 통신에 대해 이해를 해야한다.

지금까지 간과해 오던 부분을 이해하는 것이다. '클라이언트가 요청을 보내면 무슨무슨 일이 벌어져서 spring controller 를 타게되는거겠지' 하고 넘어갔을때 그 무슨무슨 일이 벌어지는 것을 말한다.
클라이언트의 http 요청은 Tomcat의 Web server가 받는다. 톰켓은 Apache Tomcat 이라고도 불리우며 Web server 와 WAS(Web Application server) 의 기능을 모두 포함한다.
사실 원래 아파치가 있고 톰캣이 따로 있는데 톰캣이 일부 아파치 기능을 발휘하기 때문에 보통 아파치 톰캣 이라고 합쳐 부른다.

Web server

클라이언트의 http 요청에 대한 일련의 과정을 처리하는 곳 이다. 정적 파일을 다루며 나중에 다룰
Servlet container 가 만든 소켓을 이용해서 연결과정을 처리 하는 녀석
이다. 정적 파일이라 하면 html,css,js 등 을 말한다.
Web Application server(앞으로는 WAS 라고 부르겠다) 와의 차이점 이라면 WAS는 동적 파일만을 다룬다. 왜 굳이 정적인 것과 동적인 것으로 나눠놨을까? 웹 브라우저 URL을 치고 들어가는 대부분은 정적 파일만을 사용한다. 그런데 굳이 동적인 부분을 처리하는 과정을 진행하는 낭비를 할 수는 없지 않는가? 따라서 동적 파일이 필요한 때가 아니라면 Web server를 통해 정적인 파일만 처리한 후 바로 Servlet container로 통신한다. 또한 이런식으로 클라이언트와 WAS 사이를 중계하면서 클라이언트와 WAS가 직접적으로 통신하는 것을 막고 각자가 독립적으로 통신되게 해준다. 이렇게 함으로써 WAS가 보안적으로 좋아지는 장점도 있다.

Servlet

서블릿? 진짜 많이 들어봤다. 디스페쳐 서블릿 이라던지 서블릿 컨테이너 라던지 어디서 많이 들어는 봤는데 뭐하는 녀석인지 모르고 지내왔다.
일반적으로 클라이언트가 request를 보내면 그에 상승하는 return 을 해줘야 하는데 이때 웹페이지 혹은 결과값을 동적으로 생성해주기 위한 역할을 하는 java 프로그램이 바로 servlet 이다.
지금 처럼 Spring 에서 서블릿을 제공해주기 전에는 동작을 위해서 Servlet 인터페이스를 직접 구현해왔다고 한다. 지금 처럼 Spring 에서 서블릿을 제공해 준다는 것은 무엇일까?

DispatcherServlet

디스페처 서블릿 이라고 많이 들어봤을 것이다. 이게 바로 Spring MVC에서 제공하는 Servlet container 역할을 하는 녀석이다. 이것 때문에 spring 프레임워크를 다루면서 서블릿 인터페이스를 직접 구현하지 않아도 알아서 해당하는 컨트롤러로 매칭을 시켜준 것이다.
디스페처 서블릿은 아주 다양한 클래스들이 구현되어 있다. 대표적으로,

HandlerMapping
Client로 부터 들어온 Request를 분석하여 매핑된 Controller가 있는지 확인한다.

HandlerAdapter
매핑 대상 Controller에게 Request 처리요청을 보낸다.

ViewResolver
Controller에서 view를 return 했을경우 해당하는 view를 찾아 client에게 return 한다.

Servlet container

그래서 톰켓의 서블릿 컨테이너는 뭔데?
톰켓의 메인 기능이라고도 할 수 있다.
서블릿 클래스의 로드, 초기화, 호출, 소멸까지의 라이프사이클을 직접적으로 관리해주는 역할을 하는것이 바로 서블릿컨테이너다. 서블릿으로 구현된 DispatcherServlet 역시 서블릿 컨테이너에서 수행된다.
아까 위에서 설명한 Web server 의 기능을 기억하는가? 동적인 response를 return 해주기 위해 소켓의 연결에 관여한다고 했는데 이때 이 소켓을 생성해 주는것이 서블릿 컨테이너 이다. 웹서버는 서블릿 컨테이너가 생성해준 소켓을 이용해서 클라이언트와 연결한다.
마지막으로 클라이언트로부터 request 를 받아오면 이를 쓰레드를 생성해 받아낸다. 이 쓰레드들의 집합 역시 서블릿 컨테이너 내에서 관리한다.
해외 커뮤니티 사이트인 레딧에서 쓰는 쓰레드와 대조해보면 아마 요청들을 따로 각자의 방을 만들어 관리하고 처리한다는 것 같다.

Spring container

Spring Document 에서 제공하는 그림이다.
맨 위에 http 통신을 위한 일련의 과정을 표현한 그림에서 마지막에 톰켓의 서블릿 컨테이너가 스프링 컨테이너에게 전달하는데 이 스프링 컨테이너에 대한 그림이다.
핸들러맵핑이 적합한 컨트롤러를 찾고 핸들러어댑터가 컨트롤러와 연결되며 뷰리졸버를 통해 동적 response를 return 한다. 이때 핸들러들이 컨트롤러와 응답하고 컨트롤러는 서비스나 레포지토리와 연결된다. DI(의존성 주입) 가 생각이 나지 않는가? Ioc(제어의 역전) 과 Bean 에 대해 학습한 내용이 이곳에서 이어진다.

서블릿 컨테이너가 서블릿의 생명주기를 관장했다면
스프링 컨테이너는 java object인 Bean 의 생명주기를 관장하며 Spring 프레임워크의 특징인 DI 와 Ioc 를 제공해주는 역할을 한다.

정리

출처 : https://taes-k.github.io/2020/02/16/servlet-container-spring-container/
참고 : https://velog.io/@kdhyo/Apache-Tomcat-%EB%91%98%EC%9D%B4-%EB%AC%B4%EC%8A%A8-%EC%B0%A8%EC%9D%B4%EC%A7%80

0개의 댓글