웹 컨테이너(Tomcat) 내부에서 일어나는 이벤트를 감지하고 자동으로 실행되는 클래스이다.
Servlet, Filter는 사용자 요청을 다루지만,
Listener는 서버 내부 객체의 생성/소멸·속성 변경을 감시한다.
동작 예:
즉, 프로그램 전체 흐름의 “감시자” 역할.
컨테이너가 이벤트를 발생시키면 Listener가 즉시 반응한다.
Context 시작 → Listener 반응
Session 생성 → Listener 반응
Request 들어옴 → Listener 반응
Attribute 추가 → Listener 반응
Listener는 관찰 대상에 따라 크게 3종류로 나뉜다.
그리고 각 객체의 attribute 변화를 감지하는 Attribute Listener가 존재한다.
웹 애플리케이션 전체의 시작과 종료 감지
주로 하는 일:
ServletContext 내부에 저장된 attribute 값 변화 감지
Application 전체에서 공유하는 값을 감시할 때 사용.
세션 생성/만료 감지
예: 방문자 수 카운트, 로그인 수 확인
Session의 attribute 변화 감지
예: 로그인 정보 저장/변경 감지
“세션에 저장된 객체" 자체가 이벤트를 감지한다.
객체가 세션에 들어갈 때(valueBound),
세션에서 제거될 때(valueUnbound) 호출된다.
예:
세션 활성화/비활성화 감지
웹 서버가 여러 대일 때(세션 클러스터링) 사용되며,
세션을 다른 서버로 옮길 때(Session Migration)를 감지한다.
request 생성/소멸 감지
예:
request attribute 변화 감지
Forward할 때 데이터 전달 과정 감시 등에 활용.
@WebListener
public class ContextListenerTest implements ServletContextListener, ServletContextAttributeListener {
public ContextListenerTest() {
System.out.println("context listener 인스턴스 생성");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("context init");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("context destroy");
}
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("context attribute added");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("context attribute removed");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("context attribute replaced");
}
}
@WebListener
public class SessionListenerTest implements HttpSessionListener, HttpSessionAttributeListener {
public SessionListenerTest() {
System.out.println("session listener 인스턴스 생성");
}
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("session created");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("session destroyed");
}
@Override
public void attributeAdded(HttpSessionBindingEvent se) {
System.out.println("session attribute added: " + se.getName());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent se) {
System.out.println("session attribute removed: " + se.getName());
}
@Override
public void attributeReplaced(HttpSessionBindingEvent se) {
System.out.println("session attribute replaced: " + se.getName());
}
}
public class UserDTO implements HttpSessionBindingListener {
@Override
public void valueBound(HttpSessionBindingEvent event) {
System.out.println("UserDTO 세션 바인딩");
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
System.out.println("UserDTO 세션 언바인딩");
}
}
@WebListener
public class RequestListenerTest implements ServletRequestListener, ServletRequestAttributeListener {
public RequestListenerTest() {
System.out.println("request listener 인스턴스 생성");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("request init");
}
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("request destroy");
}
@Override
public void attributeAdded(ServletRequestAttributeEvent srae) {
System.out.println("request attribute added");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent srae) {
System.out.println("request attribute removed");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent srae) {
System.out.println("request attribute replaced");
}
}