Spring-MVC: что такое "контекст" и "пространство имен"?
Из XmlWebApplicationContext javadoc:
По умолчанию конфигурация будет взята из "/WEB-INF/applicationContext.xml" для корневого контекста и "/WEB-INF/test-servlet.xml" для контекста с пространством имен "test-servlet" (например, для экземпляра DispatcherServlet с именем сервлета "test").
Что это означает контекст Spring?
Каков корневой контекст? Какие другие виды контекста Spring существуют?
Что такое пространство имен?
ОБНОВИТЬ:
Некоторые дополнительные вопросы:
Что такое Spring ApplicationContext - это какая-то "вещь", которая содержит компоненты, определенные в файле конфигурации XML?
Глядя на код ContextLoaderListener, похоже, что он загружает данные, определенные в XML-файлах конфигурации. Но мое веб-приложение Spring работает без определения этого слушателя или любого другого слушателя. Как это могло произойти?
В каких случаях имеет смысл иметь более одного экземпляра Spring DispatcherServlet?
Применим ли корневой контекст (данные из applicationContext.xml) к каждому экземпляру DispatcherServlet, тогда как другие контексты (например, данные из test-servlet.xml) применимы только к соответствующему DispatcherServlet (т. Е. Test)?
2 ответа
"Spring context" = Spring ApplicationContext.
"корневой контекст" в терминах веб-приложения означает основной контекст, который загружается и используется веб-приложением. Как правило, вы запускаете корневой контекст с помощью ContextLoaderListener.
Корневой контекст на самом деле не "вид" контекста. Это просто роль, которую играет контекст. У вас есть один корневой контекст в веб-приложении. Другие контексты не являются корневым контекстом. Обычно они дети корневого контекста.
Пространство имен здесь относится к области действия экземпляра Spring DispatcherServlet. Все, что здесь говорится, это то, что если вы назовете свой сервлет "test" в своем файле web.xml, то, по соглашению, Spring будет искать файл с именем "test-servlet.xml" для использования в качестве контекста этого диспетчера. Между прочим, каждый подобный контекст, который создается для диспетчера, становится потомком корневого контекста.
Изменить: Чтобы ответить на ваши новые вопросы:
- Перейдите по ссылке в первой строке моего ответа, чтобы узнать о ApplicationContext. Если у вас есть вопросы, на которые нет ответов, я бы предложил опубликовать новый вопрос SO.
- Корневой контекст не является обязательным. Если вы не определили ContextLoaderListener, то у вас просто нет корневого контекста. Когда вы используете DispatcherServlet, он запускает свой собственный ApplicationContext и оттуда получает нужные ему бины.
- Я не знаю ни одного с моей головы. Я полагаю, что если бы потребовались радикально отличающиеся конфигурации между некоторыми ресурсами URL в вашем приложении, это могло бы побудить вас сделать это.
- Да. Чтобы сформулировать это в правильных терминах, корневой контекст является родительским контекстом любого контекста, запущенного для DispatcherServlet. Бины в родительском контексте доступны через дочерний контекст, но обратное неверно.
В веб-приложении архитектура обычно делится на слои, подобные популярной структуре MVC. Таким образом, веб-приложение в основном состоит из уровня, который обрабатывает клиентские запросы, т.е. HTTPRequests, и уровня, который обслуживает эти запросы.
Подводя итог: классы, предназначенные для обработки запросов Http, т.е. контроллеры, которые отображаются на URL-адреса, входят в test-servlet.xml. Это называется WebapplicationContext, содержащим только компоненты, которые необходимы главным образом для обработки клиентских запросов.
Теперь следующая часть - это слой Service/Dao, который включает вашу бизнес-логику. Бины, выполняющие такую логику, загружаются в объект ApplicationContext.
Теперь вы можете спросить, почему они разделили эти вещи на файлы или два разных объекта.
Это потому, что приложение имеет одну и ту же бизнес-логику, которую могут использовать несколько клиентов, работающих по разным протоколам. Вы можете использовать те же уровни обслуживания для обработки RMI, а также HTTP-вызовов. Поэтому Spring создал родительский контекст, который запускается нами как ApplicationContext. И затем, если ваше приложение обрабатывает веб-запросы, вы можете создать сервлет диспетчера, который имеет свой собственный Webapplicationcontext и инициализируется как дочерний элемент родительского контекста. Таким образом, на все родительские бины можно ссылаться в потомке, и они могут быть переопределены, но не наоборот.