В комментариях к заметке Пишем простой RESTful веб-сервис на Spring Web MVC прозвучал довольно интересный вопрос, суть которого сводится к следующему: как сервер приложений находит все классы, реализующие интерфейс javax.servlet.ServletContainerInitializer, и сколько времени это занимает. Попробуем разобраться.
Часть 8 спецификации Servlet 3.0 вводит понятие "подключаемой возможности" ("plugability features"), что существенно упрощает структуру веб-приложения, а так же подключение дополнительных фреймворков. Однако, данные возможности требуют времени на сканирование JAR-архивов и файлов с классами приложения. Спецификация требует, чтобы данное сканирование производилось по-умолчанию, однако его можно частично или полностью избежать в зависимости от используемого сервера приложений.
Сканирования зависимостей и классов приложения требуют следующие возможности:
В принципе, на Stack Overflow дан довольно подробный и развернутый ответ на вопрос о том, как сервер приложений ищет классы инициализации контекста. В каталоге META-INF/services архива с библиотекой должен находиться файл javax.servlet.ServletContainerInitializer, содержащий перечисление полных имен классов, реализующих интерфейс javax.servlet.ServletContainerInitializer (по одному имени на строке). Например:
Аналогичным образом можно зарегистрировать слушатели, находящиеся непосредственно в коде самого веб-приложения, при этом файл javax.servlet.ServletContainerInitializer должен находиться в каталоге WEB-INF/classes/META-INF/services.
- Какие компоненты ищет сервер приложений при запуске.
- Servlet Container Initializer (CSI).
- Сколько времени занимает сканирование.
- Отключаем поиск компонентов веб-приложения.
- Отключаем поиск SCI.
- Выводы.
- Используемые материалы.
Какие компоненты ищет сервер приложений при запуске
Часть 8 спецификации Servlet 3.0 вводит понятие "подключаемой возможности" ("plugability features"), что существенно упрощает структуру веб-приложения, а так же подключение дополнительных фреймворков. Однако, данные возможности требуют времени на сканирование JAR-архивов и файлов с классами приложения. Спецификация требует, чтобы данное сканирование производилось по-умолчанию, однако его можно частично или полностью избежать в зависимости от используемого сервера приложений.
Сканирования зависимостей и классов приложения требуют следующие возможности:
- Впервые предложенные в спецификации Servlet 3.0:
- SCI (javax.servlet.ServletContainerInitializer);
- Веб-фрагменты (META-INF/web-fragment.xml);
- Ресурсы веб-приложения, собранные в JAR-файлах (META-INF/resources/*);
- Аннотации, определяющие компоненты веб-приложения (@WebServlet и т.д.);
- Аннотации, определяющие компоненты для сторонних библиотек, инициализируемые с помощью SCI (аннотации, которые определены в аннотации @HandlesTypes на SCI-классе. Класс конфигурации контекста приложения Spring Framework из примера - ApplicationInitializer - является таким компонентом.
- SCI (javax.servlet.ServletContainerInitializer);
- Старые возможности, впервые предложенные в ранних версиях спецификации:
- Tag Library Descriptor (TLD), определяет библиотеки тегов. Сервер приложений ищет файлы META-INF/**/*.tld.
- Tag Library Descriptor (TLD), определяет библиотеки тегов. Сервер приложений ищет файлы META-INF/**/*.tld.
Servlet Container Initializer (CSI)
В принципе, на Stack Overflow дан довольно подробный и развернутый ответ на вопрос о том, как сервер приложений ищет классы инициализации контекста. В каталоге META-INF/services архива с библиотекой должен находиться файл javax.servlet.ServletContainerInitializer, содержащий перечисление полных имен классов, реализующих интерфейс javax.servlet.ServletContainerInitializer (по одному имени на строке). Например:
psamolysov.demo.spring.restws.ServletContextInitializer1 psamolysov.demo.spring.restws.ServletContextInitializer2
Аналогичным образом можно зарегистрировать слушатели, находящиеся непосредственно в коде самого веб-приложения, при этом файл javax.servlet.ServletContainerInitializer должен находиться в каталоге WEB-INF/classes/META-INF/services.