개발 & 데이터베이스/JAVA

자바 ServletContextListener 정의 및 구현 방법

K.두부 2023. 4. 27. 12:00
반응형

ServletContextListener

웹 애플리케이션의 컨텍스트의 생명주기 이벤트를 처리하기 위한 인터페이스로 웹 애플리케이션이 시작과 종료 시점에서 특정 클래스의 메서드를 실행할 수 있는 기능을 제공한다.

 

ServletContextListener 생성 방법

어떠한 방법을 사용해도 기본적으로 해당 클래스에 ServletContextListener 를 구현해야 한다.

 

1. web.xml 이용하는 방법

 

[MyServletContextListener.java]

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContetxtListener;

public class MyServletContextListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
}

 

[web.xml]

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

위와 같이 작성을 하면 웹 애플리케이션의 시작과 종료 시점에 MyServletContextListener 클래스의 contextInitialized() 와 contextDestroyed() 메서드를 호출한다. Listener를 web.xml 파일에 추가함으로써 웹 어플리케이션이 로딩될 때 자동으로 등록되어 해당 Listener에 등록된 메서드가 호출된다.

 

2. 어노테이션을 이용하는 방법

 

[MyServletContextListener.java]

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContetxtListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyServletContextListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
}

@WebListener 어노테이션을 사용하여 MyServletContextListener클래스가 ServletContextListener로 등록된다. 1번 방법과 달리 web.xml파일에 Listener를 등록하지 않아도 되고, 어노테이션을 사용함으로써 추가로 annotation.WebListener을 import 해주면 된다.

 

✅ 두 개의 방법을 모두 사용했을 경우 어떻게 될까?

: 두 개의 방법을 한 개의 클래스에 적용했을 경우에는 웹 어플리케이션 시작/종료 시점에 하나의 인스턴스만 생성하기 때문에 한 번만 호출된다. 하지만 web.xml파일에서 동일한 클래스를 두 번 등록했을 경우에는 인스턴스가 두 개 생성되고, 이벤트에 따라서 두 개의 인스턴스가 모두 호출될 수 있으므로 주의하는 게 좋다.

 

: 두 개의 방법을 서로 다른 클래스에 적용했을 경우에 실행 순서는 보장하지 않는다. 때문에 Listener간에 서로 의존성을 띄지 않는 게 좋고, 별도의 공유 자원에 접근하지 않는게 좋다. 만약 공유 자원에 접근해야 한다면 공유 자원에 대한 접근 순서를 정해주어야 한다.

 

ServletContextListener 순서 적용하는 방법

위에서 공유 자원에 접근해야 한다면 접근 순서를 명시해 주는 게 좋다고 했다.

어떻게 순서를 명시적으로 보장할 수 있는지 알아보겠다.

 

1. Listener 클래스를 직접 호출하는 방법

: 호출된 Listener 클래스에서 다른 Listener 클래스를 직접 호출해서 순서를 제어하는 방법이다. 이 방법은 Listener 클래스 간의 의존성이 생길 수 있기 때문에 사용 시에 조심하는 게 좋다.

 

2. Context 파라미터를 이용하는 방법

: web.xml 파일에 Context 파라미터를 추가하여 Listener 실행 순서를 제어할 수 있다. 이 방법은 Listener 클래스 간의 의존성이 없다.

 

[web.xml]

<context-param>
    <param-name>listener-order</param-name>
    <param-value>com.example.MyServletContextListener, com.example.AnotherListener</param-value>
</context-param>

 

[MyServletContextListener.java]

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContetxtListener;

public class MyServletContextListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
}

public class AnotherListener implements ServletContextListener {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
}

MyServletContextListener 클래스와 AnotherListener 클래스에 순서를 지정해 줬다. param-value에 쉼표(,)로 클래스를 구분해서 작성해 주면 된다.

 

3. Ordered 인터페이스 구현

: getOrder 메서드로 실행 순서를 나타내는 정수를 반환하여 값이 작을수록 먼저 실행한다. 이 방법은 스프링프레임워크에서 제공하는 기능으로 스프링 애플리케이션에서만 사용할 수 있다.

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContetxtListener;

public class MyServletContextListener implements ServletContextListener, Ordered {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
    
    @Override
    public int getOrder() {
        return 1;
    }
}

public class AnotherListener implements ServletContextListener, Ordered {
    
    @Override
    public void contextInitialized(ServletContextEvenet sce) {
        // 웹 어플리케이션 초기화 시 수행할 작업
    }
    
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 웹 어플리케이션 종료 시 수행할 작업
    }
    
    @Override
    public int getOrder() {
        return 2;
    }
}

 

반응형