Задать вопрос

Жизненный цикл servlet'ов в Tomcat'e?

Хотелось бы спросить, верно ли я понимаю ряд вещей, ну и задать пару вопросов:

1. У tomcat'a есть набор thread'ов, которыми он управляет и в которых запускает servlet'ы.
Одновременно, параллельно может выполняться два и больше экземпляров одного и того же (класса) servlet'а.
  • Доступны ли, в таком случае, поля класса всем экземплярам этого servlet'а (работающим параллельно)?
  • Если да - выходит, на уровне классов (не методов) мне нужно использовать потокобезопасные коллекции?


2. При загрузке и выгрузки servlet'а из памяти вызываются (соответственно) методы init() и destroy(), которые позволяют загрузить ресурсы при первом запуске servlet'a и сохранить какие то данные при выгрузки servlet'а из памяти.
Если с моментом загрузки servlet'a все понятно (Если пришел запрос к servlet'у, а его нет в памяти, то он загружается),
то с моментом выгрузки из памяти не все прозрачно - При каких ситуациях servlet может быть выгружен из памяти? (Где то читал, что выгружается только при остановке tomcata / приложения, но разве servlet не может быть выгружен когда долго не работает или tomcat'у не хватает ресурсов и он хочет вместо него загрузить какой то другой servlet?)

3. Представим, что мне захотелось самому "накостылить" авторизацию пользователей на уровне servlet'ов. Каждый servlet, перед выполнением запроса пользователя проверяет авторизацию. Логика проверки авторизации вынесена в отдельный класс (не servlet).
И вот тут возникает вопрос: Если мне требуется перед началом работы всех servlet'ов инициализировать какие то общие данные, например коннект к базе или что то подобное, а потом дать возможность servlet'ам этим пользоваться, как лучше это сделать? (Мне пришло в голову только - сделать все общее статическим и вызывать напрямую, пример: ClassName.getConnect()) И правильно ли я решил, с учетом потребности разных servlet'ов параллельно ходить к базе, организовать доступ? (Вынести получение java.sql.Connection в какой то общий класс и потом отдавать его servlet'ам)
И какие могут быть подводные камни, в том что бы вынести процесс авторизации в отдельный класс и использовать его потом в разных servlet'ах? (И как им его потом передать, не делая его методы статическими?)

4. В какой то момент жизни моей программы (обычно в начальный) происходит создание подключения к базе и загрузка, общих для всех servlet'ов, ресурсов, если подключиться к базе не удалось или при загрузке пошло что то не так, смысла в дальнейшей работе tomcata и соответственно servlet'ов нет. В такой момент хотелось бы либо выключить tomcat (из java кода), либо возвращать статическую страницу с ошибкой. (Как правильно сделать и то и другое? По поводу возврата страницы с ошибкой у меня есть мысли - можно из java изменить конфиг nginx'a и заставить его перечитать, а в конфиге перенаправить все запросы к tomcat'у на страницу с сообщением об ошибке.
  • Вопрос задан
  • 1398 просмотров
Подписаться 7 Средний Комментировать
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Java
Седой и строгий
  1. Да, доступны. Да, необходимо использовать потокобезопасные коллекции.
  2. Зависит от реализации контейнера. Лучше не делать предположений на эту тему.
  3. Вы можете зарегистрировать ServletContextListener для инициализации общих для всех сервлетов данных. Но создание источника данных лучше доверить контейнеру и получить сервлетами из JNDI.

    1. Можно передать Tomcat'у параметр
      -Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE=true

    2. Наверное, можно в обработчике исключения сервлета вызывать System.exit(1)
    3. Можно в конфигурации настроить shutdown port
      <Server port="8005" shutdown="someLongAndSecretString">

      и потом в коде
      Socket socket = new Socket("localhost", 8005); 
      if (socket.isConnected()) { 
          PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); 
          pw.println("someLongAndSecretString");
          pw.close(); 
          socket.close(); 
      }



Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@karthickvarunan
A servlet life cycle can be defined as the entire process from its creation till the destruction. The following are the paths followed by a servlet.

The servlet is initialized by calling the init() method.
The servlet calls service() method to process a client's request.
The servlet is terminated by calling the destroy() method.
Finally, servlet is garbage collected by the garbage collector of the JVM.

for servlet tutorial
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы