[Spring]Servlet & Spring-webmvc
in Study on Spring & SpringBoot
Servlet 과 Spring
Servelet & Spring
1. Servlet
- HTML 등의 웹 컨텐츠를 생성하고 전달하기 위해 Servlet 클래스의 구현 규칙을 지켜 자바로 만들어진
프로그램
1-1. 작동방식
- 각각의 Servlet이 Servlet Interface를 구현
- Servlet Container가 Servlet을 관리하며 서버와 통신을 함
1-2. 나오게 된 배경
- 과거에는 static 파일만 제공
- 동적인 동작을 하는 페이지 필요해짐
- 서버와 통신하기 위한 규약이 필요해짐 ->
CGI
가 나오게 됨
1-3. CGI?
http 통신 규약을 사용하는 웹서버가 프로그램(웹 애플리케이션)과 데이터를 주고 받는 처리 규약
- 인터페이스로 여러 언어로 구현 가능
- Servlet 이전에는 직접 구현
- CGI 단점
- 1 Client - 1 Process
- 동일 CGI 구현체이더라도 매번 새로 생성
1-4. Servlet
- Servlet도 CGI 규칙에 따라 데이터를 주고 받지만 이를 서블릿을 가지고 있는
컨테이너에게 위임
하고 대신 서블릿 컨테이너와 서블릿 사이의 규칙이 존재 - 하나의 요청에서 하나의 프로세스가 껐다 켜졌다 하는 기존 CGI의 구조가 X
- 서블릿이 컨테이너 내부에서 쓰레드 단위로 요청을 처리하고 생명 주기를 가짐
- 흐름은 개발자가 아니라 컨테이너가 제어함(IoC)
- 서블릿은 웹서버 내부에서 동작하는 작은 자바 프로그램
- 일반적으로 http를 통해 웹 클라이언트들로부터 요청을 수신하고 응답
- Servlet 인터페이스를 구현하기 위해 GenericServlet을 상속 받거나 HTTP Servlet을 상속받아 구현
Servlet의 Life Cycle
- init()
- Servlet 인스턴스 생성
- Client로부터 발생한 모든 요청은 service() 를 통해 다룸
- 실제 기능이 수행되는 곳
- HTTP method (GET, POST, PUT, DELETE) 에 따라 doGet(), doPost(), doPut(), doDelete() 메서드를 호출
- Servlet이 서비스를 마치게 되면, destroy()를 통해 종료되며 GC에 의해 메모리 정리됨
- 서블릿 인스턴스 사라질 때 호출됨
- 보통 컨테이너가 종료되는 시점에 destroy() 호출
- 특정 서블릿 로드/언로드 시에도 사용
- 이미 생성된 Servlet 객체는 메모리에 남겨두어 동일한 Servlet에 대해 다시 init()을 실행하지 않고 재사용
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
2. Spring
- 자바 엔터프라이즈 개발을 편리하게 해주는 오픈소스 경량급 애플리케이션
프레임워크
Spring-webmvc의 DispatcherServlet 상속구조
- Servlet
- GenericeServlet
- HttpServlet : 여기까지가 톰캣
- HttpServletBean : 스프링
- FrameworkServlet : 스프링
- DispatcherServlet : 스프링
공부하면서..
해당 자료를 공부하면서 우연히 Spring-webmvc를 직접 열어보았더니, DispatcherServlet의 doDispatch 메서드에 하드코딩 되어 있는 부분을 발견해서 enum을 적용한 수정본을 Pull Request를 Spring에 날리기도 했다.
Spring-webmvc는 내부적으로 spring-web을 의존하고 있기 때문에 HttpMethod enum을 사용할 수 있다고 생각했기 때문에 기존 “GET”, “HEAD”로 되어 있던 하드 코딩을 spring-mvc의 HttpMethod enum 타입으로 적용했다.
PR을 받아줄지는 모르겠지만 그래도 뭔가 신기하고 재밌는 경험이었다.
https://github.com/spring-projects/spring-framework/pull/26855