Spring-MVC: что такое "контекст" и "пространство имен"?

Из XmlWebApplicationContext javadoc:

По умолчанию конфигурация будет взята из "/WEB-INF/applicationContext.xml" для корневого контекста и "/WEB-INF/test-servlet.xml" для контекста с пространством имен "test-servlet" (например, для экземпляра DispatcherServlet с именем сервлета "test").

Что это означает контекст Spring?

Каков корневой контекст? Какие другие виды контекста Spring существуют?

Что такое пространство имен?

ОБНОВИТЬ:

Некоторые дополнительные вопросы:

  1. Что такое Spring ApplicationContext - это какая-то "вещь", которая содержит компоненты, определенные в файле конфигурации XML?

  2. Глядя на код ContextLoaderListener, похоже, что он загружает данные, определенные в XML-файлах конфигурации. Но мое веб-приложение Spring работает без определения этого слушателя или любого другого слушателя. Как это могло произойти?

  3. В каких случаях имеет смысл иметь более одного экземпляра Spring DispatcherServlet?

  4. Применим ли корневой контекст (данные из applicationContext.xml) к каждому экземпляру DispatcherServlet, тогда как другие контексты (например, данные из test-servlet.xml) применимы только к соответствующему DispatcherServlet (т. Е. Test)?

2 ответа

Решение

"Spring context" = Spring ApplicationContext.

"корневой контекст" в терминах веб-приложения означает основной контекст, который загружается и используется веб-приложением. Как правило, вы запускаете корневой контекст с помощью ContextLoaderListener.

Корневой контекст на самом деле не "вид" контекста. Это просто роль, которую играет контекст. У вас есть один корневой контекст в веб-приложении. Другие контексты не являются корневым контекстом. Обычно они дети корневого контекста.

Пространство имен здесь относится к области действия экземпляра Spring DispatcherServlet. Все, что здесь говорится, это то, что если вы назовете свой сервлет "test" в своем файле web.xml, то, по соглашению, Spring будет искать файл с именем "test-servlet.xml" для использования в качестве контекста этого диспетчера. Между прочим, каждый подобный контекст, который создается для диспетчера, становится потомком корневого контекста.

Изменить: Чтобы ответить на ваши новые вопросы:

  1. Перейдите по ссылке в первой строке моего ответа, чтобы узнать о ApplicationContext. Если у вас есть вопросы, на которые нет ответов, я бы предложил опубликовать новый вопрос SO.
  2. Корневой контекст не является обязательным. Если вы не определили ContextLoaderListener, то у вас просто нет корневого контекста. Когда вы используете DispatcherServlet, он запускает свой собственный ApplicationContext и оттуда получает нужные ему бины.
  3. Я не знаю ни одного с моей головы. Я полагаю, что если бы потребовались радикально отличающиеся конфигурации между некоторыми ресурсами URL в вашем приложении, это могло бы побудить вас сделать это.
  4. Да. Чтобы сформулировать это в правильных терминах, корневой контекст является родительским контекстом любого контекста, запущенного для DispatcherServlet. Бины в родительском контексте доступны через дочерний контекст, но обратное неверно.

В веб-приложении архитектура обычно делится на слои, подобные популярной структуре MVC. Таким образом, веб-приложение в основном состоит из уровня, который обрабатывает клиентские запросы, т.е. HTTPRequests, и уровня, который обслуживает эти запросы.

Подводя итог: классы, предназначенные для обработки запросов Http, т.е. контроллеры, которые отображаются на URL-адреса, входят в test-servlet.xml. Это называется WebapplicationContext, содержащим только компоненты, которые необходимы главным образом для обработки клиентских запросов.

Теперь следующая часть - это слой Service/Dao, который включает вашу бизнес-логику. Бины, выполняющие такую ​​логику, загружаются в объект ApplicationContext.

Теперь вы можете спросить, почему они разделили эти вещи на файлы или два разных объекта.

Это потому, что приложение имеет одну и ту же бизнес-логику, которую могут использовать несколько клиентов, работающих по разным протоколам. Вы можете использовать те же уровни обслуживания для обработки RMI, а также HTTP-вызовов. Поэтому Spring создал родительский контекст, который запускается нами как ApplicationContext. И затем, если ваше приложение обрабатывает веб-запросы, вы можете создать сервлет диспетчера, который имеет свой собственный Webapplicationcontext и инициализируется как дочерний элемент родительского контекста. Таким образом, на все родительские бины можно ссылаться в потомке, и они могут быть переопределены, но не наоборот.

Другие вопросы по тегам