ServletContextListener 를 이용하여 앱이 시작할 때와 앱이 종료할 때 이벤트를 처리할 수 있다.
앱이 시작할 때 schedule 작업하는 thread 를 시작하고 앱이 종료할 때 thread 를 종료하는 방식을 응용해 봤다.
web.xml 에 우리의 listener 클래스를 등록한다.
<listener>
<listener-class>com.sample.SampleListener</listener-class>
</listener>
Listener 클래스는 대략 아래와 같다.
package com.sample; public class SampleListener implements ServletContextListener { private MyThread myThread = null; /** * 앱 시작시 불리는 함수 */ public void contextInitialized(ServletContextEvent sce) { if ((myThread == null) || (!myThread.isAlive())) { myThread = new MyThread(new MyTask()); myThread.start(); } } /** * 앱 종료시 불리는 함수 */ public void contextDestroyed(ServletContextEvent sce){ if (myThread != null && myThread.isAlive()) { myThread.quit(); } } }
실제 작업하는 스레드는 TimerTask 를 등록하고 작업이 진행되는 동안 대기하는 일을 한다.
예) 매분마다 특정 파일(backup.bat) 을 실행한다.
/** * 실제 작업하는 클래스 */ public static class MyTask extends TimerTask { @Override public void run() { try { ProcessBuilder builder = new ProcessBuilder("c:\\bin\\backup.bat"); Process p = builder.start(); InputStream in = p.getInputStream(); while (in.read() != -1) { Thread.sleep(10); } p.waitFor(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 앱이 실행되는 동안 작업을 기다리는 스레드 */ public static class MyThread extends Thread { private boolean done = false; private Timer timer; private TimerTask task; public MyThread (TimerTask task) { this.task = task; } public void quit() { this.done = true; this.interrupt(); } public boolean finishing() { return (done || Thread.interrupted()); } @Override public void run() { super.run(); timer = new Timer(); Calendar now = Calendar.getInstance(); timer.scheduleAtFixedRate(task, now.getTime(), 1000 * 60); while (!finishing()) { try { Thread.sleep(10); } catch (InterruptedException e) { break; } } timer.cancel(); } }
댓글 없음:
댓글 쓰기