Фоновая тема для приложения сервлетов Tomcat

Я не очень хорошо знаком с Tomcat, в моей голове это в основном абстрагируется как cgi-сервер, который сохраняет JVM между вызовами - я знаю, что он может сделать намного больше, чем это.

Я ищу способ запустить фоновый поток при запуске сервера Tomcat, который периодически обновлял Контекст сервера (в моем конкретном случае это поток, который прослушивает биения из некоторых других сервисов и обновляет информацию о доступности, но для этого можно представить множество применений).

Есть ли стандартный способ сделать это? Как запуск, так и обновление/запрос контекста?

Любые указатели на соответствующую документацию и/или образцы кода будут высоко оценены.

Ответ 1

Если вы хотите начать поток при развертывании WAR, вы можете определить прослушиватель контекста в файле web.xml:

<web-app>
    <listener>
       <listener-class>com.mypackage.MyServletContextListener</listener-class>
    </listener>
</web-app>

Затем реализуем этот класс примерно так:

public class MyServletContextListener implements ServletContextListener {

    private MyThreadClass myThread = null;

    public void contextInitialized(ServletContextEvent sce) {
        if ((myThread == null) || (!myThread.isAlive())) {
            myThread = new MyThreadClass();
            myThread.start();
        }
    }

    public void contextDestroyed(ServletContextEvent sce){
        try {
            myThread.doShutdown();
            myThread.interrupt();
        } catch (Exception ex) {
        }
    }
}

Ответ 2

Я ищу способ запустить фоновый поток при запуске сервера Tomcat

Я думаю, что вы ищете способ запустить фоновый поток, когда ваше веб-приложение запускается Tomcat.

Это можно сделать, используя ServletContextListener. Он зарегистрирован в web.xml и будет вызываться, когда ваше приложение запущено или остановлено. Затем вы можете создать (и позже остановить) свой поток, используя обычные способы Java для создания Thread (или ExecutionService).

Ответ 3

Вставка <load-on-startup>1</load-on-startup> в блок <servlet> в вашем web.xml заставит ваш сервлет init() произойти, как только Tomcat запустится, вместо того, чтобы ждать прибытия первого запроса. Это полезно, если вы хотите создать фоновый поток из init().

Ответ 4

Я бы немного изменил очень подробный ответ, который дал Крис; Я бы установил myThread поток Daemon на myThread.setDaemon(true);, который будет в основном поддерживать поток активным, если у вас есть другие потоки не-Daemon, которые нуждаются в фоновом потоке. Когда все эти потоки заканчиваются, ваш поток Daemon останавливается JVM, и вам не нужно обрабатывать его в contextDestroyed. Но это всего лишь мои 2 цента.

Ответ 5

Другим способом, если вы используете фреймворк spring, вы можете указать класс/поток, который вы хотите инициализировать в beans.xml. Поэтому, когда tomcat запускается, beans.xml будет инициализировать все классы, упомянутые в нем. Вы также можете передать аргументы конструктора, если это необходимо. Ниже приведен пример этого.

beans.xml

<bean id="monitoringSvc" class="com.mypackage.MonitoringService">
    <constructor-arg value="60"></constructor-arg>
</bean>

MonitoringService.java

public class MonitoringService{

     private MyThread myThread;

     public MonitoringService(int seconds){
          myThread = new MyThread(seconds);
          myThread.start();
     }
}