Фоновая тема для приложения сервлетов 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();
}
}