Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции 2025. Java. Белая / Ответы на билеты. Java

.pdf
Скачиваний:
4
Добавлен:
02.01.2026
Размер:
4.52 Mб
Скачать

Они включают в себя контейнер сервлетов как один из своих компонентов, но также предоставляют реализацию многих других спецификаций Jakarta EE (например, EJB, JPA, JMS, JTA, CDI и т.д.).

В итоге, контейнер сервлетов — это "дом" для ваших сервлетов. Он берет на себя всю низкоуровневую работу по взаимодействию с сетью, управлению жизненным циклом и предоставлению необходимых сервисов, позволяя разработчику сосредоточиться на написании бизнес-логики в сервлетах.

91. Зачем нужны сервера приложений, если есть контейнеры сервлетов?

Хотя контейнеры сервлетов (например, Tomcat, Jetty) отлично справляются с выполнением сервлетов и JSP, серверы приложений (Application Servers)

(например, WildFly, GlassFish, WebLogic, WebSphere) предоставляют гораздо более широкий набор сервисов и функциональности, необходимых для разработки и развертывания полноценных корпоративных (enterprise) приложений.

Контейнер сервлетов является, по сути, подмножеством сервера приложений. Сервер приложений включает в себя контейнер сервлетов, а также реализации других спецификаций Jakarta EE (ранее Java EE).

Основные причины, по которым могут потребоваться серверы приложений:

1. Поддержка полного стека Jakarta EE (Java EE) спецификаций:

Серверы приложений предоставляют реализации для множества корпоративных API, таких как:

EJB (Enterprise JavaBeans): Для создания распределенных,

транзакционных, компонентных бизнес-приложений.

JPA (Java Persistence API): Стандарт для объектно-реляционного отображения (ORM), упрощающий работу с базами данных.

JMS (Java Message Service): Для асинхронного обмена сообщениями между компонентами приложения.

JTA (Java Transaction API): Для управления распределенными транзакциями, охватывающими несколько ресурсов (например, несколько баз данных, очереди сообщений).

CDI (Contexts and Dependency Injection): Стандарт для внедрения зависимостей и управления жизненным циклом компонентов.

JAX-RS (Java API for RESTful Web Services): Для создания RESTful веб-

сервисов.

JAX-WS (Java API for XML Web Services): Для создания SOAP веб-

сервисов.

Bean Validation: Для валидации данных объектов.

И многие другие.

Контейнеры сервлетов, такие как Tomcat, по умолчанию поддерживают только

Servlet API, JSP, EL (Expression Language) и WebSocket. Для использования других Jakarta EE технологий в Tomcat их нужно добавлять как отдельные библиотеки и конфигурировать вручную, что может быть сложнее.

2. Управление транзакциями (расширенное):

Серверы приложений предоставляют надежное управление транзакциями,

включая поддержку распределенных транзакций (XA-транзакций) с

использованием JTA. Это критически важно для приложений, работающих с несколькими системами (например, несколько баз данных, очереди сообщений) в рамках одной атомарной операции.

Tomcat сам по себе не предоставляет полноценной поддержки JTA "из коробки".

3. Безопасность (расширенная):

Серверы приложений обычно имеют более развитые и интегрированные механизмы безопасности, включая поддержку различных схем аутентификации и авторизации (JAAS - Java Authentication and Authorization Service), интеграцию

сLDAP, Kerberos и т.д.

4.Управление ресурсами и компонентами:

Серверы приложений предоставляют централизованное управление ресурсами, такими как пулы соединений с базами данных (через , настроенные на сервере), пулы потоков, фабрики JMS-соединений и т.д. Эти ресурсы могут быть доступны приложению через JNDI.

Управление жизненным циклом EJB-компонентов, CDI-бинов.

5. Кластеризация, отказоустойчивость и балансировка нагрузки:

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

6. Администрирование и мониторинг:

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

7. Интеграция:

Лучшая интеграция между различными компонентами Jakarta EE, так как они предоставляются и тестируются как единое целое.

Когда достаточно контейнера сервлетов (например, Tomcat, Jetty):

Для простых веб-приложений, которые в основном используют сервлеты, JSP и, возможно, подключают сторонние библиотеки для ORM (например, Hibernate напрямую), обмена сообщениями или других нужд, без необходимости в полной поддержке Jakarta EE.

Для микросервисных архитектур, где каждый сервис является небольшим, независимым приложением. В этом случае легковесные контейнеры, такие как

Jetty, Spring Boot (с встроенным Tomcat, Jetty или Undertow), или Helidon, Quarkus,

могут быть более подходящими.

Если вы используете фреймворки, такие как Spring Framework, которые предоставляют многие из тех же возможностей, что и серверы приложений (например, управление транзакциями, внедрение зависимостей, ORM-интеграцию), то можно обойтись "легким" контейнером сервлетов.

Таблица сравнения (упрощенно):

Характеристика

Контейнер сервлетов

Сервер приложений (WildFly,

 

(Tomcat, Jetty)

GlassFish)

 

 

 

Основное

Выполнение сервлетов,

Выполнение

назначение

JSP

полнофункциональных

 

 

корпоративных приложений

 

 

 

Поддержка

Ограниченная (Servlet,

Полная или значительная часть

Jakarta EE

JSP, EL, WebSocket)

стека Jakarta EE

 

 

 

EJB

Нет (нужно добавлять

Да

 

отдельно)

 

 

 

 

JPA

Нет (нужно добавлять

Да (обычно интегрирован с

 

ORM-библиотеку)

Hibernate, EclipseLink)

 

 

 

JMS

Нет (нужно добавлять

Да (часто встроенный или легко

 

MQ-брокер и клиент)

интегрируемый MQ)

 

 

 

JTA (распред.

Ограниченная/Нет

Да

транзакции)

 

 

 

 

 

CDI

Нет (можно добавить

Да

 

Weld и т.п., но сложнее)

 

 

 

 

Вес и сложность

Легковесные, проще в

Более тяжеловесные, сложнее в

 

настройке

настройке и управлении

 

 

 

Время запуска

Быстрее

Медленнее

 

 

 

Типичное

Простые веб-

Крупные корпоративные

использование

приложения,

приложения, монолиты

 

микросервисы, Spring

 

 

Boot

 

 

 

 

Вывод:

Серверы приложений нужны, когда приложению требуются расширенные

корпоративные возможности, предоставляемые полным стеком Jakarta EE, такие как распределенные транзакции, EJB, развитое управление ресурсами и безопасностью "из коробки". Если же приложение не нуждается в этих сложных функциях или использует альтернативные фреймворки (например, Spring) для их реализации, то легковесного контейнера сервлетов может быть вполне достаточно.

92. Как контейнер сервлетов управляет жизненным циклом сервлета, когда и какие методы вызываются?

Контейнер сервлетов полностью управляет жизненным циклом каждого сервлета, который он развертывает. Жизненный цикл сервлета состоит из нескольких четко определенных этапов, на каждом из которых контейнер вызывает специфические методы сервлета.

Основные этапы и методы жизненного цикла сервлета (определены в интерфейсе ):

1. Загрузка класса сервлета (Loading):

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

).

Действие контейнера: Загружает файл сервлета с использованием класслоадера.

2. Создание экземпляра сервлета (Instantiation):

Когда: Сразу после успешной загрузки класса.

Действие контейнера: Создает один экземпляр класса сервлета с помощью его конструктора без аргументов (поэтому у сервлета должен быть публичный конструктор без аргументов, либо он будет предоставлен компилятором по умолчанию, если других конструкторов нет).

Важно: Для каждого объявления сервлета в или каждой аннотации

контейнер обычно создает только один экземпляр, который затем используется для обработки всех параллельных запросов к этому сервлету.

3. Инициализация сервлета (Initialization):

Когда: Сразу после создания экземпляра и только один раз за весь жизненный цикл сервлета.

Метод: Контейнер вызывает метод

.

Назначение :

Выполнить одноразовые задачи инициализации, такие как загрузка конфигурационных данных, установление соединений с базой данных

(хотя это лучше делать через

), инициализация дорогостоящих

ресурсов.

 

 

 

Объект

передается контейнером и предоставляет доступ к

параметрам инициализации сервлета (заданным в

или аннотации

) и к

 

.

 

Важно сохранить

: Если сервлет переопределяет

, он должен либо вызвать

(если

наследуется от

или

), либо сохранить объект

самостоятельно, чтобы потом можно было получить доступ к

через

 

.

уже

делает это.

Если выбрасывает или любое другое исключение, сервлет считается неинициализированным и не будет принимать запросы.

4. Обработка запросов (Request Handling / Servicing):

Когда: Каждый раз, когда контейнер получает клиентский запрос, который сопоставлен с этим сервлетом. Этот этап может происходить многократно и параллельно для разных запросов.

Метод: Контейнер вызывает метод

.

Назначение :

Это основной метод для обработки запросов.

Для HTTP-сервлетов (которые наследуют

), реализация в определяет тип HTTP-метода (GET, POST, PUT, DELETE и т.д.) и

делегирует обработку соответствующему методу (например, , ). Разработчики обычно переопределяют ,

и т.д., а не сам .

Объекты (или ) и (или ) создаются контейнером для каждого запроса и передаются в метод . содержит информацию о запросе, а используется для формирования ответа.

Многопоточность: Контейнер может вызывать метод (и,

следовательно, , ) одновременно в нескольких потоках

для одного и того же экземпляра сервлета. Поэтому код сервлета должен быть потокобезопасным, если он изменяет разделяемые данные (например, поля экземпляра). Локальные переменные методов безопасны.

5. Уничтожение сервлета (Destruction / End of Life):

Когда: Когда контейнер решает выгрузить сервлет. Это может произойти:

При остановке веб-приложения.

При остановке самого контейнера сервлетов.

Если сервлет долгое время не используется и контейнер настроен на его выгрузку для экономии ресурсов (реже).

Метод: Контейнер вызывает метод .

Назначение :

Выполнить задачи очистки перед тем, как экземпляр сервлета будет уничтожен сборщиком мусора.

Освободить ресурсы, захваченные в методе (например, закрыть соединения с базой данных, если они были открыты напрямую, сохранить состояние).

Метод вызывается только один раз за весь жизненный цикл сервлета, после того как все потоки, обрабатывающие запросы к этому сервлету, завершили свою работу. Новые запросы к этому сервлету после начала вызова приниматься не будут.

Схема жизненного цикла:

Контейнер стартует / Первый запрос к сервлету

Сервлет загружен?

Нет

Unsupported markdown: list

Unsupported markdown: list

Unsupported markdown: list

Успешно

Контейнер останавливается / Приложение выгружается

Сервлет активен

Да

Unsupported markdown: list

Экземпляр сервлета

Да

удаляется GC

Сервлет готов к работ

Каждый запрос Запрос обработан

 

Unsupported markdown: list

Се

Важные моменты:

Один экземпляр (по умолчанию): Если не используется специальная конфигурация (например, , который устарел и не рекомендуется), контейнер создает только один экземпляр сервлета. Потокобезопасность: Разработчик должен позаботиться о потокобезопасности доступа к полям экземпляра сервлета, так как один и тот же объект используется для обработки множества запросов параллельно. Локальные переменные методов безопасны.

Методы и вызываются только один раз.

Метод (и, соответственно, , ) вызывается для каждого запроса.

Понимание жизненного цикла сервлета критически важно для правильной инициализации ресурсов, обработки запросов и освобождения ресурсов при завершении работы.

93. Что такое «дескриптор развертывания»?

Дескриптор развертывания (Deployment Descriptor) в контексте Java веб-

приложений — это конфигурационный XML-файл, который описывает, как вебприложение должно быть развернуто и сконфигурировано контейнером сервлетов (или сервером приложений). Стандартное имя этого файла — , и он должен находиться в каталоге веб-приложения.

Назначение дескриптора развертывания ():

предоставляет контейнеру сервлетов инструкции и метаданные о вебприложении, включая:

1. Объявление сервлетов (Servlets):

Определение имен сервлетов и полных имен их классов.

Параметры инициализации () для каждого сервлета.

Порядок загрузки ().

2. Маппинг сервлетов (Servlet Mappings):

Связывание URL-шаблонов с именами сервлетов. Контейнер использует эти маппинги, чтобы определить, какой сервлет должен обработать входящий запрос на определенный URL.

3. Объявление фильтров (Filters):

Определение имен фильтров и полных имен их классов.

Параметры инициализации для фильтров.

4. Маппинг фильтров (Filter Mappings):

Связывание фильтров с URL-шаблонами или именами сервлетов. Фильтры могут перехватывать и обрабатывать запросы до того, как они достигнут

сервлета, и ответы после того, как сервлет их сгенерировал.

5. Объявление слушателей (Listeners):

Определение классов слушателей, которые реагируют на события жизненного цикла веб-приложения (например, инициализация/уничтожение контекста, создание/уничтожение сессии, добавление/удаление атрибутов).

6. Параметры контекста (Context Parameters):

Параметры инициализации, доступные для всего веб-приложения (через

).

7. Конфигурация сессий (Session Configuration):

Например, таймаут сессии ().

8. Определение MIME-типов (MIME Mappings):

Связывание расширений файлов с MIME-типами.

9. Страницы приветствия (Welcome Files):

Список файлов (например, , ), которые контейнер должен попытаться отобразить, если запрос идет к корневому URL приложения

 

или к каталогу.

 

10.

Страницы ошибок (Error Pages):

 

Маппинг кодов ошибок HTTP (например, 404, 500) или типов исключений Java

 

на конкретные страницы (HTML или JSP), которые должны отображаться

 

пользователю в случае ошибки.

11.

Настройки безопасности (Security Constraints):

 

Определение защищенных ресурсов, требуемых ролей для доступа, методов

 

аутентификации.

 

12.

Ссылки на ресурсы (Resource References):

 

Например, для

(JNDI-имена).

13.

Другие конфигурации: Версия Servlet API, отображаемое имя приложения и т.д.

Эволюция :

До Servlet 3.0: был обязательным для любого веб-приложения. Вся конфигурация сервлетов, фильтров и слушателей должна была быть явно прописана в этом файле.

Начиная с Servlet 3.0: стал опциональным. Многие конфигурации теперь можно выполнять с помощью аннотаций непосредственно в Java-классах:

для объявления сервлетов и их маппингов.

для объявления фильтров и их маппингов.

для объявления слушателей.

для параметров инициализации.

И другие.

Если присутствует в приложении Servlet 3.0+ (или 2.5 с флагом

), он может переопределять или дополнять

конфигурации, заданные аннотациями, или использоваться для тех

конфигураций, которые нельзя задать аннотациями (например, некоторые настройки безопасности, страницы ошибок, глобальные параметры контекста). Флаг в элементе в указывает контейнеру игнорировать аннотации и использовать только конфигурацию из

.

Пример фрагмента (до-аннотационная эра или для специфических настроек):