ejyoo's 개발 노트

ServletContext 라이프 사이클 본문

BackEnd/JAVA Spring

ServletContext 라이프 사이클

ejyoovV 2021. 5. 27. 11:53

서블릿 2.3 부터 라이프 사이클

서블릿 2.3 이전에는 

서블릿 컨테이너 라이프 사이클과 관련된 처리를 정확하게 할 수 없었다.

서블릿 컨테이너를 가동하거나 멈출 때 발생하는 이벤트가 없기 때문에

자원의 초기화 시점이나 반납 시점이 명확하지 않았다.

 

하지만 서블릿 2.3에 들어서면서 이러한 문제가 해소되었다.

2.3에 새롭게 추가된 컨텍스트 라이프 사이클 관련 이벤트인 ServletContextEvent가 추가되었고

세션의 라이프 사이클과 관련된 HttpSessionEvent가 추가되었다.

 

ServletContextEvent를 통해서 전체 웹 어플리케이션의 초기화 시점과 종료시점을 선형적으로 처리할 수 있게 되었고

HttpSessionEvent를 통해서 특정 사용자의 세션관리를 보다 명확하게 할 수 있게 되었다.

 

컨텍스트(Context)는 하나의 웹 어플리케이션을 나타낸다.

보통 컨텍스트는 [Servlet엔진]/webapps 디렉토리에 위치시키는 경우가 많다.

톰캣의 경우

[톰캣루트]/webapps 디렉토리에 WAR 파일을 위치시키거나

D:\A_TeachingMaterial\6.JspSpring\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

디렉토리를 생성하면 자동으로 컨텍스트에 추가된다.

 

서블릿 2.3은 컨텍스트의 라이프 사이클을 2단계로 정의하고 있다.

첫번째 단계는 컨텍스트 초기화(또는 생성) 단계이며

두번째 단계는 컨텍스트의 종료(또는 삭제) 단계이다.

일반적으로 서블릿 엔진이 처음 시작할 때 각각의 컨텍스트가 초기화되며

서블릿 엔진을 종료할 때 컨텍스트도 함께 종료된다.

컨텍스트 라이프 사이클

컨텍스트의 초기화는 사용자들이 웹 브라우저를 사용하여 웹 어플리케이션을 실행하는 시점보다 이전에 발생하기 때문에,

웹 어플리케이션에서 사용하는 데이터베이스 커넥션이나 객체의 풀 또는 각종 설정 정보등을 초기화하기에 가장 알맞은 시점이다.

 

또한 컨텍스트의 종료는 서블릿 엔진을 종료하기 이전에 수행되기 때문에 어플리케이션에서 사용하고 있는 자원을 반납하기에 가장 알맞은 시점이 된다.

 

 


ServletContextEvent와 ServletContextListener

 

서블릿 컨테이너는 컨텍스트의 초기화되거나 종료되는것을 알리기 위해서 

이벤트 - 리스너 방식을 사용한다.

컨텍스트의 초기화나 종료 시점에서 서블릿 컨테이너는 ServletContextEvent를 발생시키며,

이 이벤트는 컨텍스트의 정보를 지정하는 web.xml을 통해서 지정된 ServletContextListener에 전달된다.

 

* javax.servlet.ServletContextListener 인터페이스

ServletContextListener 인터페이스는 AWT의 다른 이벤트 리스너와 마찬가지로 이벤트가 발생하는 시점에 호출되는 메소드들을 선언하고 있고 목록은 아래와 같다.

  • public void contextInitialized(ServletContextEvent sce) : 컨텍스트가 초기화될 때 호출된다.
  • public void contextDestroyed(ServletContextEvent sce) : 컨텍스트가 종료될 때 호출된다.

 

* 서블릿 컨테이너에 컨텍스트 이벤트 리스너 등록

AWT 프로그래밍에서 이벤트 리스너를 작성하면 이벤트를 발생시키는 이벤트 소스(source)에 리스너를 등록해주는 것처럼, 

컨텍스트 이벤트 리스너도 이벤트 소스를 발생시키는 서블릿 컨테이너에 등록해주어야 한다.

AWT의 경우와 다른 점이 있다면 리스너의 등록이 프로그래밍을 통해서 이루어지는 것이 아니라 web.xml 파일을 통해서 이루어 진다는 점이다.

 

* 서블릿 2.3 규약

서블릿 2.3 규약에는 컨텍스트 이벤트 리스너를 등록할 때 사용되는 새로운 태그인 <listener>를 추가했으며

이 태그를 사용하여 작성한 리스너를 등록하면 된다.

<listener>
    <listener-class>완전한 클래스 이름</listener-class>
  </listener>

<listener> 태그는 하나의 리스너를 나타내며, <listener>에 중첩되어있는 <listener-class> 태그를 사용하여 리스너 클래스를 지정하게 된다.

예를들어 만든 리스너를 등록하고자 하는 경우 아래와 같이 하면된다.

<listener>
	<listener-class>kr.or.ddit.listener.ApplicationContextInitListener</listener-class>
</listener>

<listener> 태그가 <servlet> 태그 이전에 위치하는지 

아니면 다른 태그 전에 위치하는 지 

http://java.sun.com/dtd/web-app_2_3.dtd 에 정의되어있는 web.xml 파일의 DTD 내용 중 일부이다.

<!ELEMENT web-app (icon?, display-name?, description?, distributable?,
context-param*, filter*, filter-mapping*, listener*, servlet*,
servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,
error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,
login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>

위에서 볼 수 있듯이 web.xml 파일에서 <listener> 태그는 다른 태그들과 마찬가지로 <web-app> 태그에 중첩되어 ㅓㅇ의되는데,

<filter-mapping> 태그와 <servlet> 태그 사이에 위치하면 된다.