728x90
🖐 들어가기 전에!
Web Server (웹 서버)
- 인터넷을 기반으로 클라이언트에게 웹 서비스를 제공하는 컴퓨터
- 그러나 웹 서버에서 제공할 수 있는 데이터는 웹에서 처리가 가능한 HTML, CSS, 이미지 등의 정적인 데이터로 한정된다
WAS (Web Application Server)
- Web Application : 웹에서 실행되는 응용 프로그램
- WAS는 웹 애플리케이션과 서버 환경을 만들어 동작시키는 기능을 제공하는 소프트웨어 프레임워크이다
- WAS에서는 비즈니스 로직도 수행이 가능하다
- 쉽게 생각하면 웹 서버 + 웹 컨테이너 형태라고 생각하면 된다!
- 컨테이너란 jsp, servlet을 실행시킬 수 있는 소프트웨어이다
- 자바 계열에서는 웹 애플리케이션 컨테이너라고도 불리며, 웹 애플리케이션에 배포되는 공간이다
- WAS는 웹 애플리케이션을 실행시켜 필요한 기능을 수행하고 그 결과를 웹 서버에게 전달한다
- php, jsp, asp와 같은 언어들을 사용하여 동적인 페이지를 생성할 수 있는 서버이다
- 프로그램 실행 환경과 데이터베이스 접속 기능을 제공한다
Servlet이란?
- 동적인 페이지를 만들기 위해 웹 서버에 붙이는 프로그램 중 하나이다
- 서블릿이 요구하는 구현 규칙을 지키면서 서블릿을 정의하면 HTTP 요청 정보를 쉽게 사용할 수 있고, 처리 결과를 응답으로 쉽게 변환할 수 있다
- 따라서 서블릿을 통해 웹 요청을 다루게 되면, 개발자들은 비즈니스 로직에만 집중할 수 있게 된다!
- 개발자들은 처리하고 싶은 요청 메서드에 해당하는 doXXX 메서드를 찾아서 매핑한 후 재정의해주기만 하면 된다
- 참고로 서블릿은 웹 컨테이너에 의해 생명주기가 관리된다
서블릿 컨테이너와 서블릿이 호출되는 과정
- 서블릿 컨테이너는 서블릿을 담고 관리하는 객체이다
- 서블릿은 싱글톤으로 관리되기 때문에 요청마다 생성 및 소멸 과정이 모두 포함되지는 않는다
- Servlet Reques / Servlet Response 객체를 생성한다
- 서블릿 컨테이너가 설정 파일을 참고하여 매핑할 Servlet을 확인한다
- 서블릿 컨테이너 내에 해당 서블릿 인스턴스 존재의 유무를 확인하여 없으면 생성한다 -> init() 호출
- Servelt container에 스레드를 생성하고, res / req 인자로 service를 실행한다
- 해당 결과를 웹 서버에게 네트워크를 통해서 전달한다
여러 요청을 처리하는 방법
- 한 요청을 처리하는 도중에 다른 요청이 들어오면 멀티스레드로 요청을 처리하게 된다
- 여러 스레드가 생성되고 위의 그림과 같이 스레드 당 다른 서블릿이 처리할 수 있고 반대로 여러 스레드에서 한 서블릿의 여러 요청을 동시에 처리할 수 있게 된다
- 그러나 스레드를 생성하는 것 자체가 큰 비용을 발생시키고, 다른 스레드로 전환하는 Context Switch가 많은 오버헤드를 야기하기 때문에 멀티스레딩을 사용할 때는 주의해야 한다
- 또한 스레드 생성에 제한을 두지 않으면 많은 요청을 처리하기 위해 그만큼 스레드를 생성하다가 서버의 하드웨어 한계를 넘어서 서버가 터질수도 있다
요청 당 서블릿을 정해주는 방법의 한계점
- 멀티스레딩을 다뤄야하기 때문에 관리의 측면에서 어려움이 있다
- 또한 핸들러의 공통 로직이 매번 중복되기 때문에 개발의 측면에서도 어려움이 존재한다
위의 문제점을 쉽게 이해하기 위해 예시를 들어보자
- 예를 들어 카페에서 메뉴마다 담당 직원이 따로 있다고 가정해보자
- 그러면 제조해야 되는 메뉴는 모두 다르지만, 주문을 받고 계산하고 포장하는 작업이 매번 중복된다
공통 로직 중복 문제의 해결법 - Front Controller
- 공통 로직이 중복되는 문제를 해결하기 위해 전면에서 주문을 받고 계산하고 포장하는 부분을 뺴내어 매니저로 둔다
- 매니저는 손님의 요청을 앞단에서 처리할 수 있는 일을 전담하게 된다
- 이를 Front Controller 패턴이라고 한다
Dispatcher Servlet
- 스프링 MVC도 Front Controller 패턴을 따르는데 이 때 모든 요청을 받는 전면 컨트롤러(서블릿)을 Dispathcer Servlet이라고 부르는 것이다!
- 즉, 서블릿을 하나만 두고 모든 요청을 받을 수 있도록 하는 것이다
- 따라서 이전에 서블릿을 개별적으로 다루었을 땐 요청마다 서블릿을 정의하고, 요청을 수행할 때마다 매번 스레드를 생성해야 하는 번거로움이 있었다
- 그러나 Dispathcer Servlet을 사용함으로써 하나의 서블릿만 정의하고, 그 서블릿이 모든 요청을 수행할 수 있도록 한다
Dispatcher Servlet의 Web 요청 처리 방법
- 앞에서 들었던 카페 예시를 다시 보면, 이 경우 만약 손님이 너무 많이 와서 전면 매니저도 일이 밀리는 경우가 발생할 수 있다
- 따라서 위는 좋은 역할 분담 구조가 아니라고 할 수 있다
- 앞의 문제점을 해결하려면 위와 같이 역할을 분리하는 것이 좋을 것이다
- 전면 매니저가 모든 요청을 처리하되, 계산 / 음료 / 포장 담당 직원을 따로 분리하는 것이다
- 이를 Dispatcher Servlet에 적용해서 생각해보자
- Dispatcher Servlet이 모든 요청을 다 받고, Handler Mapping이 요청을 처리할 때 컨트롤러를 찾아서 반환한다
- Handler Adapter는 해당 컨트롤러의 메서드를 호출하여 처리 로직을 수행하는 역할을 한다
- 그 후 처리 결과를 Model And View 객체로 변환해서 다시 Dispatcher Servlet에게 넘긴다
- 그러면 Dispatcher Servlet이 View Resolver를 이용하여 View를 찾거나 생성한다
- 이렇게 얻은 View에 모델로 들어왔던 데이터를 넣어 응답 결과 생성을 요청해서 사용자가 볼 수 있는 JSP나 Thymleaf 와 같은 데이터를 담은 출력 파일로 응답하게 되는 것이다
- 앞의 과정만 살펴보면 개발자가 해야할 일이 더 많아진 것 같지만, 스프링을 사용하여 개발한다면 사실상 개발자가 구현할 부분은 위의 노란 부분(XX 처리 Handler) 뿐이다
- Handler Mapping, Handler Adapter, View Resolver 부분도 원래는 개발자가 직접 처리해야 했지만, 이 부분들은 Dispatcher Servlet이 스프링 컨테이너로부터 주입을 받아서 사용하고 동작하게 된다
💡 스프링 컨테이너
프로그램이 동작하는 동안 사용되는 자바 객체들을 프레임워크가 대신 관리하고 보관하기 위해서 사용되는 객체이다
Dispatcher Servlet의 구조
- Dispatcher Servlet 내에는 2개의 컨텍스트가 존재한다
- Servlet WebApplicationContext : 웹 요청 처리 관련 객체들이 관리됨
- Root WebApplicationContext : 웹 요청처리와 관련된 빈 외의 컴포넌트들(Service, Repository) 관련 객체들이 관리됨
- 해당 컨테이너들이 개발에 필요한 부분이나 Dispatcher Servlet이 요청을 처리할 때 필요한 부분을 주입해준다
- 따라서 개발자는 Servlet 설정 파일만 잘 작성해주면, 설정대로 생성된 객체가 스프링 컨테이너에서 관리되고 필요한 부분에서 주입받아 Dispatcher Servlet이 알아서 사용할 수 있게 된다!
참고)
https://www.youtube.com/watch?v=NyhbNtOq0Bc
https://www.youtube.com/watch?v=calGCwG_B4Y
https://www.youtube.com/watch?v=2pBsXI01J6M&t=466s
https://unequaled-peach-7e5.notion.site/Dispatcher-Servlet-56a2f1a95a06438f8b3c1f9a54d4c1c0
728x90
'야미스터디 > Spring' 카테고리의 다른 글
[Spring] IoC, DI, AOP 📌 - 작성중 (0) | 2022.11.29 |
---|---|
[Spring] Swagger 📌 (0) | 2022.10.06 |
[Spring] Spring vs EJB 📌 (1) | 2022.09.20 |
[Spring] bean vs component 📌 (0) | 2022.09.08 |
[Spring] maven vs gradle 📌 (0) | 2022.08.18 |
댓글