Servlet Life Cycle
  Dashboard > Java와 JEE > Home > Servlet Life Cycle
Community
  Java와 JEE Log In | Sign Up   View a printable version of the current page.  
Added by 박재성, last edited by 박재성 on 9월 27, 2005  (view change)
Labels: 
(None)

서블릿 Listener가 정확히 무슨 역할을 하며, 어떤 곳에 활용할 수 있을지 찾아보다가 서블릿의 기초인 Life Cycle 문서를 보게 되었네요. 그 동안 너무 기초에 소홀한 느낌이 들어서 다시 한번 되짚어 보고 있습니다. 처음에 서블릿을 배울 때는 이해하지 못했던 부분들이 지금 다시 보니까 쉽게 이해가 되는군요. 그래서 가끔씩 과거에 읽었던 책이나 문서들을 다시금 되짚어 볼 필요가 있는거 같습니다.

이러다가 오늘 중으로 서블릿 Listener가 뭐하는 놈인지 찾을 수나 있으려는지..뭐 못찾으면 내일도 있으니까요..h2.

온라인 문서

Servlet Life Cycle 문서를 참고하면 Servlet의 Life Cycle에 대하여 깊이 있게 이해할 수 있다.

Introduction

서블릿의 Life Cycle은 Container에 의하여 관리된다. 모든 서블릿이 사용되기 위해서는 web.xml에 Mapping하여 사용하는 것이 일반적이다. 만약 Mapping된 서블릿에 요청을 보낸다면 다음과 같은 과정을 통하여 서블릿이 실행된다.

  • 서블릿 인스턴스가 존재하지 않는다면..
    • 클래스 로더는 서블릿 클래스를 로드한다.
    • 서블릿 클래스의 인스턴스를 생성한다.
    • 서블릿 클래스의 init() 메써드를 호출함으로서 초기화를 진행한다. 서블릿의 초기화 과정에 대해서는 Initializing a Servlet 문서를 참고하기 바란다.
  • 서블릿 인스턴스가 존재한다면..
    • 서블릿의 service() 메써드에 request, response 객체를 전달한다. 서블릿의 service() 메써드에 대해서는 Writing Service Methods 문서를 참고하기 바란다.

Handling Servlet Life Cycle Events

아직 감은 잘 오지 않지만 암튼 나름대로 정리하자면, Servlet의 Life Cycle 상에서 Event가 발생할 경우 Event 성격에 따른 Listener를 만들어 등록했다가 특정 작업을 할 수 있도록 하는 것으로 이해한다.

javax.servlet.ServletContextListener를 상속하는 Listener는 Container가 시작할 때와 종료할 때 원하는 작업을 수행할 수 있다. ServletContext에 Servlet Life Cycle의 예제를 보면서 이해하면 다음과 같다.

import database.BookDB;
import javax.servlet.*;
import util.Counter;

public final class ContextListener
  implements ServletContextListener {
  private ServletContext context = null;
  public void contextInitialized(ServletContextEvent event) {
    context = event.getServletContext();
    try {
      BookDB bookDB = new BookDB();
      context.setAttribute("bookDB", bookDB);
    } catch (Exception ex) {
      System.out.println(
        "Couldn't create database: " 
        + ex.getMessage());
    }
    Counter counter = new Counter();
    context.setAttribute("hitCounter", counter);
    context.log("Created hitCounter"
      + counter.getCounter());
    counter = new Counter();
    context.setAttribute("orderCounter", counter);
    context.log("Created orderCounter"
      + counter.getCounter());
  }

  public void contextDestroyed(ServletContextEvent event) {
    context = event.getServletContext();
    BookDB bookDB = context.getAttribute(
      "bookDB");
    bookDB.remove();
    context.removeAttribute("bookDB");
    context.removeAttribute("hitCounter");
    context.removeAttribute("orderCounter");
  }
}

Container가 시작할 때 Application 전체에서 사용할 수 있는 전역변수처럼 인스턴스를 생성하여 ServletContext로 접근할 수 있는 어느 곳에서나 접근이 가능하도록 구현하고 있다. 즉, Container가 시작할 때 한번만 초기화하고 다음 요청부터 이용할 필요가 있는 기능들이 있다면 이와 같은 기능을 사용하면 좋을 것으로 생각한다.

web.xml에 위 Listener를 등록하는 과정은 다음과 같다.

<listener>
  <listener-class>listeners.ContextListener</listener-class>
</listener>

위에서 초기화된 인스턴스를 이용하는 예제는 다음과 같다.

public final class HitCounterFilter implements Filter {
  private FilterConfig filterConfig = null;
  public void doFilter(ServletRequest request,
    ServletResponse response, FilterChain chain) 
    throws IOException, ServletException {
    ...
    StringWriter sw = new StringWriter();
    PrintWriter writer = new PrintWriter(sw);
    ServletContext context = filterConfig.
      getServletContext();
    Counter counter = (Counter)context.
      getAttribute("hitCounter");
    ...
    writer.println("The number of hits is: " +
      counter.incCounter());
    ...
    context.log(sw.getBuffer().toString());
    ...
  }
}

Servlet Filter는 특정 애플리케이션의 모든 요청을 처리하는 것이 가능하다. 위와 같이 Servlet Filter로 진입하는 모든 요청에 대하여 HitCount를 계산하는 것이 가능하다.

Spring 프레임워크가 ServletContextListener를 이용해서 XML에 저장되어 있는 내용을 초기화한다. Spring 프레임워크의 초기화 과정을 이해한다면 Listener를 이해하는데 많은 도움이 될 것으로 생각한다. 조만간 Spring 프레임워크도 이해할겸 한번 분석해 보자. 이것도 재밌는 작업이 되겠군.


Site running on a free Atlassian Confluence Open Source Project License granted to JavaJiGi Project. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.1 Build:#643 1월 22, 2007) - Bug/feature request - Contact Administrators