Разница между applicationContext.xml и spring-servlet.xml в Spring Framework
- Являются
applicationContext.xml
а такжеspring-servlet.xml
как-то связаны в Spring Framework? - Будут ли файлы свойств объявлены в
applicationContext.xml
быть доступным дляDispatcherServlet
? - На связанной ноте, зачем мне
*-servlet.xml
совсем? ПочемуapplicationContext.xml
одного недостаточно?
6 ответов
Spring позволяет вам определять несколько контекстов в иерархии родитель-потомок.
applicationContext.xml
определяет компоненты для "корневого контекста веб-приложения", то есть контекста, связанного с веб-приложением.
spring-servlet.xml
(или как там еще это называется) определяет компоненты для контекста приложения одного сервлета. В веб-приложении их может быть много, по одному на каждый сервлет Spring (например, spring1-servlet.xml
для сервлета spring1
, spring2-servlet.xml
для сервлета spring2
).
Бобы в spring-servlet.xml
может ссылаться на бобы в applicationContext.xml
, но не наоборот.
Все контроллеры Spring MVC должны идти в spring-servlet.xml
контекст.
В большинстве простых случаев applicationContext.xml
контекст не нужен. Обычно используется для хранения bean-компонентов, которые совместно используются всеми сервлетами в веб-приложении. Если у вас есть только один сервлет, то в этом нет особого смысла, если только вы не используете его специально.
Сценарий 1
В клиентском приложении (приложение не является веб-приложением, например может быть приложением Swing)
private static ApplicationContext context = new ClassPathXmlApplicationContext("test-client.xml");
context.getBean(name);
Нет необходимости в web.xml. ApplicationContext как контейнер для получения сервиса bean. Нет необходимости в контейнере веб-сервера. В test-client.xml может быть Simple bean без удаленного взаимодействия, bean с удаленным взаимодействием.
Вывод: в сценарии 1 applicationContext и DispatcherServlet
не связаны.
Сценарий 2
В серверном приложении (приложение, развернутое на сервере, например, Tomcat). Доступ к услуге через удаленное взаимодействие из клиентской программы (например, приложение Swing)
Определите слушателя в web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
При запуске сервера ContextLoaderListener
создает компоненты, определенные в applicationContext.xml.
Предполагая, что вы определили следующее в applicationContext.xml:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
Бины создаются из всех четырех файлов конфигурации test1.xml, test2.xml, test3.xml, test4.xml.
Вывод: в сценарии 2 applicationContext и DispatcherServlet
не связаны.
Сценарий 3
В веб-приложении с пружиной MVC.
В web.xml определите:
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
Когда Tomcat запускается, бины, определенные в springweb-servlet.xml, создаются. DispatcherServlet
продолжается FrameworkServlet
, В FrameworkServlet
бобовая инстанция происходит для весенней паутины. В нашем случае springweb - это FrameworkServlet.
Вывод: в сценарии 3 applicationContext и DispatcherServlet
не связаны.
Сценарий 4
В веб-приложении с пружиной MVC. springweb-servlet.xml для сервлета и applicationContext.xml для доступа к бизнес-службе в программе сервера или для доступа к службе БД в другой программе сервера.
В web.xml определено следующее:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
При запуске сервера, ContextLoaderListener
создает компоненты, определенные в applicationContext.xml; при условии, что вы заявили здесь:
<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />
Все бины создаются из всех четырех test1.xml, test2.xml, test3.xml, test4.xml. После завершения создания экземпляра bean-компонента, определенного в applicationContext.xml, создаются экземпляры bean-компонента, определенного в springweb-servlet.xml.
Таким образом, порядок создания экземпляров является корневым, это контекст приложения, а затем FrameworkServlet.
Теперь ясно, почему они важны в каком сценарии.
Еще один момент, который я хочу добавить. В spring-servlet.xml
мы включаем компонентное сканирование для пакета контроллера. В следующем примере мы включаем аннотацию фильтра для пакета контроллера.
<!-- Scans for annotated @Controllers in the classpath -->
<context:component-scan base-package="org.test.web" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
В applicationcontext.xml
мы добавляем фильтр для оставшегося пакета за исключением контроллера.
<context:component-scan base-package="org.test">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
Проще говоря,
applicationContext.xml
определяет бины, которые являются общими для всех сервлетов. Если ваше приложение имеет более одного сервлета, то определение общих ресурсов в applicationContext.xml
будет иметь больше смысла.
spring-servlet.xml
определяет бины, которые связаны только с этим сервлетом. Вот это диспетчерский сервлет. Итак, ваши Spring MVC контроллеры должны быть определены в этом файле.
Нет ничего плохого в определении всех бобов в spring-servlet.xml
если вы используете только один сервлет в своем веб-приложении.
В технологии Servlet, если вы хотите передать какой-либо ввод определенному сервлету, вам нужно передать параметр init, как показано ниже.
<servlet>
<servlet-name>DBController</servlet-name>
<servlet-class>com.test.controller.DBController</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>John</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DBController</servlet-name>
<url-pattern>/DBController</url-pattern>
</servlet-mapping>
Если вы хотите передать некоторые данные, которые являются общими для всех сервлетов, тогда вам нужно настроить контекстный параметр. пример
<context-param>
<param-name>email</param-name>
<param-value>admin@example.com</param-value>
</context-param>
Точно так же, когда мы работаем с Spring MVC, нам нужно предоставить некоторую информацию в предопределенный сервлет, предоставляемый Spring, то есть DispatcherServlet, через init param. Таким образом, конфигурация выглядит следующим образом: здесь мы предоставляем spring-servlet.xml в качестве параметра init для DispatcherServlet.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>Spring MVC App</display-name>
<servlet>
<servlet-name>SpringController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringController</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
Снова нам нужен контекстный параметр. Это применимо для всего приложения. Таким образом, мы можем предоставить корневой контекст applicationcontext.xml. Конфигурация выглядит следующим образом:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationcontext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>SpringController</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringController</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
Контексты приложения предоставляют средства для разрешения текстовых сообщений, включая поддержку i18n этих сообщений. Контексты приложения предоставляют общий способ загрузки файловых ресурсов, таких как изображения. Контексты приложения могут публиковать события в bean-компонентах, которые зарегистрированы как слушатели. Некоторые операции над контейнером или bean-компонентами в контейнере, которые должны выполняться программным способом с фабрикой bean-компонентов, могут быть декларативно обработаны в контексте приложения. Поддержка ResourceLoader. Ресурсный интерфейс Spring предоставляет гибкую универсальную абстракцию для обработки низкоуровневых ресурсов. Сам контекст приложения является ResourceLoader, следовательно, предоставляет приложению доступ к экземплярам ресурсов, специфичным для развертывания. Поддержка MessageSource: контекст приложения реализует MessageSource, интерфейс, используемый для получения локализованных сообщений, причем фактическая реализация является подключаемой.