어떠한 이벤트가 발생하면 호출되어 처리하는 객체를 말한다.
Listner를 사용하기 위해서는 인터페이스를 구현하는 클래스를 만들어야한다.
웹 어플리케이션의 시작과 종료시 자동으로 발생되는 이벤트를 수행하기 위한 메소드를 정의한 인터페이스이다.
웹 컨테이너가 처음 구동될 때 실행되는 메소드이다.
웹 컨테이너가 종료될 때 실행되는 메소드
컨테이너에 저장된 속성 값들의 변화가 있을 때 수행하기 위한 메소드를 정의한 인터페이스이다.
HTTP 세션이 활성화 되거나 비활성화 되려할 때 혹은 속성 값들이 추가, 삭제, 변경될 경우 수행하기 위한 인터페이스 이다.
HTTP 세션에 대한 속성 값이 변경되었을 경우 수행하기 위한 인터페이스
세션에 대한 내용이 새로 생성되어 세션이 활성화 되었을 때 발생하는 이벤트를 수행하기 위한 인터페이스
클라이언트의 세션 정보에 대한 바인딩이 이루어졌을 경우 감지되는 이벤트를 수행하기 위한 인터페이스
내가 개발하려는 것은 spring server가 실행될 때 fileWatch 기능이 있는 Thread 를 생성하여 백그라운드에 계속 남겨두는 것 이다.
즉, web application 실행 event를 받는 listner안에 thread 내용을 구현하면될 것 이다.
따라서 ServletContextListener interface를 구현한 class 를 생성할 것 이다.
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
import lombok.extern.slf4j.Slf4j;
@WebListener
@Slf4j
public class FileWatch implements ServletContextListener, Runnable{
private Thread thread;
private boolean isShutdown = false;
private ServletContext sc;
public void startFileWatch(){
if(thread == null)
thread = new Thread(this, "Watch Thread");
if(!thread.isAlive())
thread.start();
}
@Override
public void run() {
Thread currentThread = Thread.currentThread();
while(currentThread == thread && !this.isShutdown){
try{
log.info("file watch is running");
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.info("fileWatch end");
}
@Override
public void contextInitialized(ServletContextEvent sce) { // 생성자, 즉 web application 이 실행될때 실행된다.
log.info("contextInitialized call");
startFileWatch();
ServletContextListener.super.contextInitialized(sce);
}
@Override
public void contextDestroyed(ServletContextEvent sce) { // 소멸자, web application이 삭제될 때 실행된다.
log.info("contextDestroyed call");
this.isShutdown = true;
try {
thread.join();
thread = null;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
ServletContextListener.super.contextDestroyed(sce);
}
}
이후 servlet 컨테이너에 등록하기위해 applcation 실행 class에 ServletComponentScan Annotation을 사용한다.
@SpringBootApplication
@ServletComponentScan
public class NHNStorageApplication {
public static void main(String[] args) {
SpringApplication.run(Test.class, args);
// .addApplicationListener(new ApplicationPidFileWriter());
}
}
다른 방법도 찾는도중
@PostConstruct annotation의 존재를 알았다.
객체가 인스턴스화된 직후 서비스에 투입되기 전에 호출되어야 하는 클래스의 메서드를 표시하는 데 사용되는 Java 주석입니다. 개체를 사용하기 전에 필요한 초기화를 수행하기 위한 콜백 메서드로 자주 사용됩니다.
내겐 이 방법이 더 좋은것 같아서
Thread 는 @PostConstruct annotation 을 이용해 생성하기로 결론냈다.