인프런 김영한님의 스프링 MVC 1편 강의 내용을 바탕으로 작성한 글입니다.
이전 글에서 클라이언트의 요청을 처리해주는 웹 애플리케이션 서버에 대해 아주 간단하게 알아보았다. 그렇다면 웹 애플리케이션 서버는 무슨 일을 할까?
클라이언트가 아래와 같은 요청을 보내왔다고 생각해보자.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
대충 이름이 kim
이고 나이가 20세인 회원의 정보를 등록해달라는 요청이다. WAS는 이 요청을 처리하기 위해 아래의 업무들을 전부 처리해주어야 한다.
저장 요청 하나 처리하는데 해야 할 일이 너무 많다. 그래서 톰캣같은 WAS는 서블릿이라는 걸 지원한다.
@WebServlet(name = "helloServlet", urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
// 애플리케이션 로직
}
}
서블릿은 비즈니스 로직을 제외한 나머지 업무를 처리해준다. HttpServlet
를 상속받으면 서블릿을 편리하게 사용할 수 있다.
위의 코드는 /hello
라는 URL로 요청이 오면 실행되는 서블릿 코드이다. 매개변수로는 HTTP 요청 정보를 편리하게 사용할 수 있는 HttpServletRequest
와 HTTP 응답 정보를 편리하게 사용할 수 있는 HttpServletResponse
를 받고 있다.
init()
메서드를 통해 서블릿 인스턴스가 초기화딘다.service()
메서드가 호출된다.destroy()
메서드를 통해 서블릿 인스턴스가 종료된다.서블릿 객체에는 static main()
메서드가 없기 때문에, 외부 컨테이너의 제어 하에 호출되어야 한다. 그래서 톰캣처럼 서블릿을 지원하는 WAS 내에는 서블릿 컨테이너라는 게 존재하는데, 말 그대로 서블릿을 관리해주는 컨테이너이다. 서블릿 컨테이너는 다양한 기능을 지원한다.
서블릿 객체를 자동으로 생성, 초기화, 호출, 종료하며 생명주기를 관리해준다. 서블릿 메서드를 호출하고, 서블릿이 실행될 때 필요로 하는 것들을 제공하는 일을 담당한다는 의미이다. HTTP 요청이 들어올 때마다 객체를 생성하는 건 비효율적이기 때문에, 서블릿 컨테이너가 시작되는 시점에 서블릿 객체 인스턴스를 미리 만들어두었다가 재활용한다. 서블릿 컨테이너가 종료되면 서블릿 객체도 함께 소멸된다.
하나의 웹 애플리케이션 서버는 수많은 요청을 처리해야 한다. 그 중에서는 동시에 오는 요청도 있기 마련이다. 이러한 요청들을 감당하기 위해 서블릿 컨테이너는 요청마다 쓰레드를 할당하여 동시 요청을 처리할 수 있도록 지원한다.
웹 애플리케이션 서버에서 서블릿을 이용해 HTTP 요청을 처리하는 과정은 다음과 같다.
localhost:8080/hello
로 HTTP 요청을 보낸다.helloServlet
을 실행한다. 서블릿 컨테이너는 request 객체와 response 객체를 서블릿에게 넘겨준다.💡request, response 객체는 요청 메세지를 기반으로 생성되므로 매 요청마다 새로 생성된다.
함께 읽어보기: https://docs.oracle.com/cd/A97688_16/generic.903/a97680/overview.html