- Кто-нибудь знает, как Spring на самом деле загрузочные файлы?
- Какие экземпляры созданы и кем?
- Я действительно хочу знать, кто создает экземпляры WebApplicationContext и ContextLoader. Это работа Tomcat?
Как Spring фактически загрузочный файл?
Ответ 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
вместо его экземпляра).
Ответ 2
См. http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/htmlsingle/#context-create.
Принцип заключается в объявлении ServletContextListener в стандартном дескрипторе webapp (web.xml). Такой слушатель действительно создается экземпляром контейнера и вызывается, когда приложение инициализируется и когда оно уничтожается.
Spring предоставляет такой ServletContextListener: ContextLoaderListener, который, как указывает его имя, загружает контекст Spring, когда webapp инициализированы.