⊙ 서블릿의 동작 원리

 

아파치 톰캣 : 서블릿/JSP 컨테이너(서블릿 컨테이너) 즉 웹 서버이면서 서블릿 컨테이너

톰캣이 구동되면 자바가상머신(JVM)이 구동되어 자바 문법을 따르는 서블릿을 처리 할 수 있는 환경을 제공한다.

 

  • ① 브라우저에서 서블릿을 요청한다.
  • ② WAS 안에 웹 서버가 서블릿 요청을 인식하여 서블릿 컨테이너에게 서블릿을 수행하도록 넘겨준다.
  • ③ 서블릿은 스레드를 기동하여 해당 서블릿 객체를 생성하여 이를 수행한다.
  • ④ 서블릿 객체의 작업이 종료되면 기동되었던 스레드가 종료된다.
  • ⑤ 서블릿 수행 결과가 웹 서버에 전송된다.
  • ⑥ 이를 클라이언트에 전송한다.

 

⊙ 서블릿의 라이프 사이클

서블릿은 수행 속도가 빠르다. 그 이유는 두 번째 이상의 요청이 첫 번째 요청인 경우와 다르게 처리되기 때문이다.

 

서블릿이 첫 번째 요청인 경우에는 서블릿 클래스를 찾아 메모리에 로딩하여 인스턴스(객체)를 생성한다. 이때 생성된 서블릿 인스턴스는 메모리에 계속 남아 있게 되므로 이후부터는 서블릿이 호출되어도 서블릿 인스턴스가 다시 생성되지 않고 이미 메모리에 로딩된 서블릿으로부터 서비스만 받기 때문에 수행 속도가 빠르다.

 

반면 PHP, ASP는 클라이언트들의 요청이 있을 때마다 작업을 처음부터 새롭게 하는 인터프리터 방식이기 때문에 수행 속도가 느리다.

우선 객체가 생성되면서 init() 메소드가 단 한번 호출되는데 init() 메소드에서는 주로 초기화 작업을 한다.

그 후 클라이언트의 요청이 있을 때 doGet() 혹은 doPost() 메소드가 실행된다. 여러 클라이언트가 동시에 요청을 하더라도 스레드가 생성되므로 동시에 doGet() 혹은 doPost() 메소드가 실행되기 때문에 수행 속도가 빠르다.

서블릿이 더 이상 서비스를 하지 않을 경우 destroy() 메소드가 호출된다.

 

서블릿의 라이프 사이클을 코드로 확인해본다.

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/LifeCyCle")
public class LifeCyCle extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	int initCount = 1;
	int doGetCount = 1;
	int destroyCount = 1;
    
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드는 첫 요청만 호출됨 : " + initCount++);
	}

	public void destroy() {
		System.out.println("destroy 메소드는 톰캣이 종료될 때만 호출됨 : "+ destroyCount++);
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet 메소드가 요청때마다 호출됨 : " + doGetCount++);
	}
}

실행결과
init 메소드는 첫 요청만 호출됨 : 1 
doGet 메소드가 요청때마다 호출됨 : 1 
doGet 메소드가 요청때마다 호출됨 : 2 
doGet 메소드가 요청때마다 호출됨 : 3 
doGet 메소드가 요청때마다 호출됨 : 4 
doGet 메소드가 요청때마다 호출됨 : 5

새로고침을 여러 번 하여 해당 페이지를 여러 번 요청 후 실행결과를 보면 init() 메소드는 처음 실행시킬 때 한 번만 호출되고 doGet() 매소드만 여러 차례 호출되는 것을 볼 수 있다.

+ Recent posts