[ Servlet Life Cycle ]
: 서블릿 생명주기의 주요 메서드로는 Servlet interface의 init(), service(), destroy()가 있다.
: Web Container(or Servlet Container or WAS)가 담당한다.
> 서블릿이 생성되어 서비스하고 소멸되는 과정
- ① 사용자로부터 특정 페이지에 대한 요청이 들어오면 컨테이너로 요청 정보가 전해진다
- ② 컨테이너는 배포서술자(DD:Deployment Descriptor)의 서블릿 맵핑 정보를 참조하여 해당 서블릿을 호출한다.
- is loaded ? 해당 Servlet / JSP 객체가 메모리에 적재되었는지 여부를 확인한다
no → ③번으로 (최초 요청 시에만 실행 : 1번 실행)
yes → ④번으로 (요청 시마다 실행 : n번 실행) - ③ 호출된 MyServlet이 로딩(class loading) → Servlet or JSP 객체가 생성 된다.
- ④ 서블릿이 초기화(init) 된다.
- ⑤ 요청에 대한 내용을 처리하고 응답해준다.
- ⑥ 서블릿이 소멸된다.(서비스 종료시, 서블릿 인스턴스가 메모리에서 해제되기 전 실행)
출처 : https://myblog.opendocs.co.kr/archives/438
[ 메서드 정리 ]
→ init(ServletConfig config) : 해당 서블릿의 초기화 작업을 위해 정의, 서블릿 당 한 번 실행
→ service(request, response)
: 해당 서블릿이 사용자에게 서비스하기 위해 정의, 클라이언트 요청시마다 호출
: doGet() / doPost()와 연결
→ destroy() : 해당 서블릿이 메모리에서 해제되기 전에 실행
> 코드로 살펴보자
package step1;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LifeCycleServlet
*/
public class LifeCycleServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
//1. 생성자 : servlet 객체 생성
public LifeCycleServlet() {
super();
System.out.println(getClass().getName()+" 객체 생성");
}
// 2. init() : 서블릿 초기화
@Override
public void init() throws ServletException {
System.out.println("init() 실행");
}
// 3. 요청내용 처리& 응답
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("service method 계열인 doGet() 실행");
}
// 4. destroy() 서블릿 소멸
@Override
public void destroy() {
// TODO Auto-generated method stub
super.destroy();
}
}
browser에서 새로고침을 계속해서 실행해도,
init()은 한번만 실행되고,
service method는 요청 시마다 실행되고,
destroy()는 서버를 stop했을 때 실행된다.
> Container가 Servlet 객체를 만드는 것을 보여주는 예제
servlet 생성 시에, class를
class LifeCycleServlet extends HttpServlet { }
위와 같이 public class가 아닌 (default) class 로 생성하면 500 오류가 발생한다.
왜일까 ?
우리는 우리가 사용할 Servlet을 생성할 때,
서블릿 계층구조에 따라 HttpServlet, GenericServlet을 상속받는 것이기 때문이다.
: defualt는 다른 패키지의 class에 접근하지 못한다. (protected는 다른 패키지 class 접근 불가한건 같으나, 상속일 경우에는 OK)
(→ 컨테이너가 객체를 만든다!)
> 다수의 클라이언트(브라우저)가 와도
Servlet 내에 있는 instance variable(count)는 공유되는 것을 확인하는 예제
package step2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CountServlet
*/
public class CountServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private int count; //접속 수 저장
//1. Servlet 객체 생성
public CountServlet() {
super();
System.out.println("CountServlet 객체 생성");
}
//2. init() : 서블릿 초기화
@Override
public void init() throws ServletException {
System.out.println("init() 실행");
}
//3. 요청내용 처리 & 응답
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<h3>");
out.println("접속수");
out.println(++count);
out.println("</h3>");
out.close();
}
//4. destroy() : 서블릿 소멸
@Override
public void destroy() {
System.out.println("destroy() 실행");
}
}
브라우저 결과
정리해보자!
FindProductServlet에 접속해서 상품을 검색하는 사용자 요청이 1000번
FindProductServlet의
객체 생성(웹 컨테이너가 생성)은 몇번 ? => 1번
init() 초기화는 몇번 ? => 1번
service() 의 doGet()은 몇번 ? => 1000번
Servlet/JSP는 스레드 thread 기반으로 동작하기 때문에,
해당 서블릿 객체를 한 번 생성하고,
서비스를 할 때에는 한번 만든 서블릿 객체를 이용해 서비스한다.
service() 계열 메서드를 실행시킬 thread만 다수 생성되어 실행시킨다 !
'Java Web Programming > 3. Servlet' 카테고리의 다른 글
[Servlet] Web 중간 정리! (2) | 2020.08.24 |
---|---|
[Servlet] 서블릿 ServletConfig / ServletContext (2) | 2020.08.21 |
[Servlet] 서블릿 Hierarchy 계층 구조 (Web Container, Web Server) (0) | 2020.08.21 |
CODE [Servlet] check box 연습 예제 (3) | 2020.08.21 |
[Servlet] form 연동 (2) | 2020.08.20 |