finerss's world!

ServletContextListener +1

컨텍스트 파라미터에는 String 밖에 저장할 수 없다. 객체를 XML 배포 서술자에 넣을 수 없다

예를들어 애플리케이션에 있는 모든 서블릿이 데이터베이서 Connection객체를 공유하고 싶을 떄는 어떻게할까?

오늘날 컨텍스트 파라미터를 이용한 가장 일반적인 방법은 컨텍스트 파라미터에
 
DataSource 검색명(lookup name)을 저장하는 것이다.

그런다음 누가 String인 검색명을 실제 DataSource 객체로 바꾸면 되는데 이것을 누가 하느냐가 문제이다.

서블릿안에 넣자니 어떤 서블릿이 가장 먼저 호출된지 알수없다. 만약 가장먼저 호출되지않으면 그보다 호출이 먼저된

서블릿은 DataSource 객체를 공유받지 못할것이다.

방법은 컨텍스트 초기화 이벤트에 리스닝 하는 것이다. 이를 이용하면 컨텍스트 초기화 파라미터를 읽은 다음

애플리케이션이 클라이언트에게 서비스하기 전에 특정 코드를 실행할 수 있다.

하지만 이방법을 누가 하느냐가 문제인데 서블릿도 JSP도 아닌 클래스가 필요하다

이클래스는 다음의 두가지 ServletContext이벤트(초기화(생성)와 소멸)에 귀 기울이고 있어야한다.

즉 다음의 기능을 가진 클래스여야한다

 - 컨텍스트가 초기화(애플리케이션 배포)되는 걸 알아차릴수 있어야한다
ServletContext로부터 컨텍스트 초기화 파라미터를 읽는다.
데이터베이스를 연결하기 위하여 초기화 파라미터 검색명(lookup name)을 사용한다
데이터베이스 Connection 객체를 속성(Attribute)에 저장한다.
-컨텍스트가 종료(애플리케이션 서비스가 내려가는)되는 걸 알아차릴수있어야한다
데이터베이스 연결을 닫는다.
 ServletContextListener 클래스

import javax.servlet.*;

public class MyServletContextListener implementes ServletcontextListener
                                                                    //컨텍스트 리스너는 ServletContextListener만 구현하면된다
       public void contextInitialized(ServletContextEvent event){
              //여기에 데이터베이스 연결을 초기화 하는 코딩을한다.
              //그리고 이를 컨텍스트 속성에 저장한다.
       }

       public void contextDestroyed(ServletContextEvent event){
            //여기에 데이터베이스 연결을 닫는 코딩을 한다.
      }
}

리스너 작성후 컨테이너에게 우리가 리스너를 만들었음을 알려주기위해

DD(web.xml)에 <listener>요소에 클래스 이름만 기재하면 된다.

<servlet> 
        <servlet-name>xxx</servlet-name>
        <servlet-class>xxx</servlet-class>
</servlet>

<Context-param>
      <param-name>adminEmail</param-name>
      <param-value>abc@daum.com</param-value>
</Context-param>

<listener>
      <listener-class>
            com.example.MyServletContextListener
      </listener-class>
</listener>




전체적인 그림을 보면
애플리케이션 시작(초기화)에서부터 마지막(서블릿 실행) 까지 한번보면


1. 컨테이너는 DD를 읽는다. 물론<listener> 요소와 <context-param> 요소도 읽는다.
2. 컨테이너는 ServletContext 객체를 생성한다. 애플리케이션에서 이객체를 공유한다.
3. 컨테이너는 컨텍스트 초기화 파라미터의 이름/값 쌍(String 쌍)을만든다.(여기선하나만있다고가정)




4. 컨테이너는 생성한 컨텍스트 초기화 파라미터의 String 쌍을 ServletContext 객체에 설정한다.
5. 컨테이너는 MyServletContextListener 클래스 인스턴스를 만든다.
6. 컨테이너는 리스너의 contextInitialized() 메소드를 호출합니다. 인자로 ServletContextEvent를 넘긴다.
   이 이벤트 객체를 가지고 ServletContext에 접근한다. 코드에서는 ServletContextEvent로 접근한
   ServletContect로 컨텍스트 초기화 파라미터 값을 읽는다.



7. 리스너가 ServletContextEvent에게 ServletContext에 대한 참조를 요청한다..
8. 리스너가 ServletContext에게 컨텍스트 초기화 파라미터 breed에 대한 값을 요청한다..
9. 리스너는 초기화 파라미터를 가지고 Dog객체를 생성한다.
10. 리스너는 ServletContext의 속성으로 Dog를 설정한다.


11. 컨테이너는 새로운 서블릿을 생성한다( 풀어서 말하면 초기화 파라미터로 ServletConfig를 생성하고,
      여기에 ServletContext에 대한 참조를 설정한 다음,
      서블릿 init() 메소드를 호출한다).
12. 서블릿은 요청을 받고는, ServletContext에게 dog속성에 매핑된 객체 인스턴스를 요청한다.
13. 서블릿은 Dog객체의 getBreed()메소드를 호출한다. (그다음 HttpResponse에 이내용을 쓴다).

'공부 > Sevlets&JSP' 카테고리의 다른 글

동기화  (0) 2011.06.29
Attribute(속성)  (0) 2011.06.28
ServletConfig 와 ServletContext  (0) 2011.06.27
Request, Response  (0) 2011.06.27
서블릿 생명주기와 API  (0) 2011.06.24