티스토리 뷰
1. 서블릿 탄생 배경
: 예전에 웹 프로그램은 html과 image 등의 정적인 데이터만을 주고 받을 수 있었다. 시간이 지남에 따라 사용자의 요구에 따라 동적 데이터도 주고 받을 수 있어야 했는데 이때 탄생된 것이 CGI 이다.
CGI란?
: Common Gatewat Interface의 약자로 http 통신 규약을 사용하는 웹서버가 웹애플리케이션과 데이터를 주고받은 처리 규약, 인터페이스므로 여러 언어로 구현이 가능했다.
클라이언트는 웹 서버에게 요청을 보내고 웹 서버는 웹 애플리케이션에게 요청을 전달한다. 웹 애플리케이션에서는 CGI를 구현한 구현체로 동적인 데이터를 처리하여 response하게된다.
단점
- 모든 요청은 하나의 프로세스로 이루어진다. 이렇게 되면 많은 메모리 소모가 일어나게 된다.
- 두 개 이상의 프로세스에 대하여 CGI 구현체가 같아도 각각 구현체를 생성해야 한다. 즉 싱글톤 패턴을 지원하지 않는다.
이러한 단점을 보완하여 새로 나온 것이 서블릿이다.
2. Servlet
:자바에서 만든 CGI의 확장형 인터페이스이다. 멀티스레드 방식으로 동작하여 하나의 요청은 스레드로 처리하여 메모리 낭비를 줄이고 싱글톤 패턴을 지원하여 같은 구현체는 한번만 생성하여 사용하게 된다.
요청이 들어오면 서블릿 컨테이너 내부에서 스레드 단위로 요청을 처리한다. 이러한 요청 처리의 흐름은 개발자가 아닌 서블릿 컨테이너가 제어하게 된다.
서블릿 생명주기
- init() : 해당 서블릿에 대한 요청이 들어오면 초기에 단 한번만 이 메소드를 생성하여 서블릿 인스턴스를 생성한다. 이미 생성된 서블릿 객체는 메모리에 남겨두어 동일한 서블릿에 대해 다시 Init()을 실행하지 않고 재사용하게 된다.
- Service() : 스레드 사용자 요청을 처리한다. dopost(), doget() 등..
- destroy() : 애플리케이션이 종료될 떄 호출되는 메소드이다. 이떄는 모든 서블릿이 소멸된다.
이러한 서블릿을 Spring Web MVC에서는 어떻게 사용하는가?
자세한 동작과정은 아래의 포스팅을 참고하기 바라고 해당 포스팅에서는 Spring이 사용하는 DispatcherServlet에 대하여 알아보도록 하겠다.
DispatcherServlet의 등장
: 클라이언트로부터 요청이 들어오면 Tomcat과 같은 웹 서버 내의 서블릿 컨테이너가 요청을 받게되는데 이 때 모든 요청을 제일 앞에서 핸들링하는 서블릿 구현체이다. 톰켓의 HttpServlet을 상속받아 구현된다.
Web.xml 역할의 축소
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jspx</url-pattern>
</servlet-mapping>
DispatcherServlet이 등장하기 이전에는 모든 요청에 대하여 각각의 서블릿 구현체를 생성하여 URL 매핑을 하였다.
DispatcherServlet을 사용하게 되면서 해당 애플리케이션으로 들어오는 모든 요청(/)을 핸들링해주므로 각각의 URL에 대한 서블릿 구현체 설정을 하는 수고로움을 덜 수 있게 되었다.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mappin>
하지만 모든 요청을 처리하다 보니 정적인 파일도 Controller로 넘겨 버리게 되는데 이러한 문제에 대한 해결책은 두가지가 있다.
1. 클라이언트의 요청을 2가지로 분리하여 구분하는 것
: /app 과 /resource로 url을 구분하여 DispathcerServlet을 거칠지 않을지를 결정하는 방식이다. 이 방식은 모든 요청에 대해 위의 url을 붙이기 떄문에 직관적인 설계가 어렵다는 단점이 있다.
2. 모든 요청을 컨트롤러에 등록하는 것
: 무식한 방법이다.
<mvc: resources />를 이용한 정적 데이터 처리
스프링 프레임워크에서 servlet-context.xml 파일을 보면 아래의 코드를 확인할 수 있다.
<resources mapping="/resources/-*" location="/resources/" />
이것은 만약 DispatcherServlet에서 해당 요청에 대한 컨트롤러를 찾을 수 없는 경우 2차적으로 설정된 경로에서 요청을 탐색하여 자원을 찾아내는 것이다.
이러한 방법을 사용하여 리소스 관리를 지원하고 확장도 용이하게 된다.
'BackEnd > SpringBoot' 카테고리의 다른 글
[Spring] - Filter VS Interceptor (0) | 2021.02.17 |
---|---|
[Spring] - Spring Web MVC 동작 과정 (0) | 2021.01.18 |
[Spring] - 프록시 패턴과 스프링 AOP (0) | 2020.11.16 |
[Spring]-스프링부트 프로젝트 예외처리 전략 (0) | 2020.11.11 |
[Spring] - SpringBoot에서 Redis Cache 사용하기 (0) | 2020.10.15 |