Ответ 1
Подход слушателя контекста сервлета (web.xml)
- Веб-приложение WAR развертывается пользователем.
- Контейнер сервлета (Tomcat) читает
web.xml
. - Слушатель контекста сервлета
ContextLoaderListener
создается (если он определен как<listener>
внутриweb.xml
) с помощью контейнера сервлета.-
ContextLoaderListener
создает новыйWebApplicationContext
с конфигурацией XML контекста приложения. - Контекст ROOT beans регистрируется и создается экземпляром
BeanFactory
внутри контекста приложения.
-
-
DispatcherServlet
создается контейнером сервлета.-
DispatcherServlet
создает свой собственныйWebApplicationContext
(WEB-INF/{servletName}-servlet.xml
по умолчанию) с контекстом ROOT в качестве родителя. - Ваш сервлет beans регистрируется и создается
BeanFactory
в контексте приложения. -
DispatcherServlet
регистрирует по умолчанию beans в случае, если вы сами не предоставили их.
-
Подход инициализатора контейнера сервлетов (не web.xml)
Это возможно с функциями Servlet 3.
- Веб-приложение WAR развертывается пользователем.
- контейнер сервлета ищет классы, реализующие
ServletContainerInitializer
через JavaServiceLoader
. - Spring
SpringServletContainerInitializer
найден и создан экземпляр контейнером сервлета. - Spring инициализатор читает путь к классу веб-приложений и ищет
WebApplicationInitializer
. - Ваш
WebApplicationInitializer
найден (btw. проверить его JavaDoc!!!) и создал экземплярSpringServletContainerInitializer
.- Ваш
WebApplicationInitializer
создает новый ROOTWebApplicationContext
с конфигурацией на основе XML или@Configuration
. - Ваш
WebApplicationInitializer
создает новый сервлетWebApplicationContext
с конфигурацией на основе XML или@Configuration
. - Ваш
WebApplicationInitializer
создает и регистрирует новыйDispatcherServlet
с контекстом предыдущего шага.
- Ваш
- контейнер сервлета завершает инициализацию веб-приложения и создает компоненты, которые были зарегистрированы их классом на предыдущих этапах (в моем примере не было).
На основе Java подход гораздо более гибкий. Вы можете оставить создание контекста до DispatcherServlet
или даже всего экземпляра самого DispatcherServlet
для контейнера сервлета (просто зарегистрируйте сервлет DispatcherServlet.class
вместо его экземпляра).