Servlet
서블릿이란 HTTP 요청과 응답을 처리하는 자바 클래스이다.
서블릿 컨테이너(Tomcat)가 요청을 서블릿 객체에 전달하고 서블릿은 HttpServletRequest / Response로 데이터를 읽고 응답한다.
서블릿의 생명 주기
@WebServlet(name = "itemServlet", urlPatterns = "/exam/item")
public class ItemServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
// 여기서 DB 커넥션 풀 획득, 캐시 로딩 등 "초기화" 수행(필수는 아님)
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("application/json;charset=UTF-8");
try (PrintWriter out = resp.getWriter()) {
String id = req.getParameter("id");
out.print("{\"path\":\"/exam/item\",\"id\":\"" + (id != null ? id : "") + "\"}");
}
}
@Override
public void destroy() {
// init()에서 연 외부 자원 정리
}
}
서블릿은 보통 미리 로드 되거나 첫 요청 시 1회 생성되어 재사용된다
객체는 생성후 최초 1회만 init 메서드에서 DB 커넥션 풀 획득, 캐시 로딩 등 초기화를 수행하고 호출된 메서드와 일치하는 메서드를 찾아 실행하고(get 요청이면 doGet, post면 doPost) 만약 일치하는 메서드가 없다면 405응답을 하게된다.
서블릿은 기본적으로 하나의 인스턴스로 다수의 요청을 받게되는 구조로 상태를 가지면 안돼고 서블릿 인스턴스가 정상 종료될 때 destroy메서드를 실행해 외부 자원을 반납하게 된다
ServletContainer
서블릿에는 위에 내용에 추가로 서블릿 스펙에서 HTTP 요청/응답 서블릿 생명주기, 디스패처 타입 등 동작을 등을 인터페이스나 추상 클래스 형태로 정의하는데 그것의 구현한 것이 서블릿 컨테이너이고 Spring에선 Tomcat이 서블릿 컨테이너의 역할을 한다.
스펙 수준에서 반드시 제공하는 기능
- 컴포넌트 생명주기 관리
- 서블릿/ 필터를 리스너의 로딩 -> 인스턴스 생성 -> init() -> service()분기 ->destory() 호출까지의 과정을 표준 순서로 관리
- request, response 객체 생성
- 소켓에서 읽은 HTTP를 파싱해 HttpServletRequest / Response를 생성
- Disfetching(매칭)과 실행 파이프라인
- Host, Context, servlet을 순서대로 매칭
- 등록된 Filter Chain을 전/후로 처리
- I/O 버퍼링, 커밋 관리
- 멀티스레드 지원 및 관리
- 컨테이너 내부에서 스레드 풀에서 요청을 처리할 스레드를 관리
- 요청이 들어오면 스레드 풀에서 사용 가능한 스레드를 할당하고 요청 처리가 끝나면 반환
- 사용 가능한 스레드가 없다면 큐에서 대기 하고 대기중인 스레드가 생긴다면 할당받아 사용
동작 흐름
- 커넥터가 HTTP 요청 수신
- 서블릿 컨테이너가 HTTP 요청을 파싱해 HttpServletRequest/Response 객체로 만든다
- 호스트/ 컨텍스트/ 매핑 결정(컨테이너 디스패치)
- 가상 호스트 선택 -> 웹앱(Context) 선택 -> 서블릿 매핑 결정(정확 일치 -> 경로 매핑 -> 확장자 매핑 순으로 우선순위를 둠)
- 매핑 정보는 web.xml 또는 @WebServlet 으로 등록되어 있음
- 이 단계에선 서블릿 메서드가 호출되지 않고, 어디로 보낼지만 확정하는 과정
- 필터 체인 전처리
- 인증, 로깅, 인코딩 등
- 서블릿 service() 호출
- 컨테이너는 최적으로 찾은 서블릿 인스턴스의 service()를 호출하고 service()는 메서드별로 분기 (doGet, doPost, doput()등)
- 멀티스레드 환경으로 인스턴스 필드에 가변 상태를 두지 않는다
- 서블릿이 응답 헤더/본문 작성
- resp.setStatus(), setHeader(), setContentType() 등 헤더 설정
- resp.getWriter() 또는 getOutputSteam()으로 본문을 작성하면 버퍼에 쌓였다가 커밋 된다
- 필터 체인 후처리
- 타이머 기록등
- 컨테이너가 소켓으로 전송 & 정리
- request, response 객체는 스코프 종료로 참조에서 벗어나 GC 대상이 된다
'CS > Spring' 카테고리의 다른 글
JPA (1) | 2025.08.27 |
---|---|
DispatcherServlet (3) | 2025.08.25 |
AOP 정리 (5) | 2025.08.13 |