- Кто-нибудь знает, как 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 инициализированы.