Одним из основных предлагаемых преимуществ Spring Framework является возможность выбора. В общем смысле, Spring не заставляет использовать или покупать какую-либо конкретную архитектуру, технологию или методологию (хотя он, конечно, имеет некоторые рекомендации касательно тех или иных). Эта свобода выбора архитектуры, технологии или методологии, наиболее подходящей для разработчика или его команды разработчиков, пожалуй, наиболее явно проявляется в веб-сфере, где Spring предлагает собственные веб-фреймворки (Spring MVC и Spring WebFlux), но в то же время поддерживает интеграцию с рядом популярных веб-сторонних фреймворков.

Общая конфигурация

Прежде чем погрузиться в особенности интеграции каждого поддерживаемого веб-фреймворка, давайте сначала рассмотрим общую конфигурацию Spring, которая не является специфичной для какого-либо одного веб-фреймворка. (Этот раздел в равной степени применим к собственным вариантам веб-фреймворка Spring).

Одна из концепций (за неимением лучшего слова), поддерживаемых моделью облегченных приложений Spring, – это многоуровневая архитектура. Помните, что в "классической" многоуровневой архитектуре веб-уровень является лишь одним из многих. Он служит одной из точек входа в приложение на стороне сервера и делегирует полномочия объектам-сервисам (фасадам), которые определены на сервисном уровне, по работе со специфическими (и не зависящими от технологии представления) бизнес-сценариями использования. В Spring эти объекты-сервисы, любые другие бизнес-объекты, объекты доступа к данным и т.д. существуют в отдельном "бизнес-контексте", который не содержит объектов веб-уровня или уровня представления (объекты представления, такие как контроллеры Spring MVC, обычно конфигурируются в отдельном "контексте уровня представления"). В этом разделе подробно описано, как можно сконфигурировать контейнер Spring (WebApplicationContext), содержащий все "бизнес-бины" вашего приложения.

Переходя к конкретике, все, что нужно сделать, это объявить ContextLoaderListener в стандартном файле Java EE-сервлета web.xml вашего веб-приложения и добавить секцию contextConfigLocation(в том же файле), которая определяет, какой набор конфигурационных XML-файлов Spring необходимо загрузить.

Рассмотрим следующую конфигурацию <listener/>:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Далее рассмотрим следующую конфигурацию <context-param/>:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

Если вы не укажете параметр контекста contextConfigLocation, ContextLoaderListener будет искать файл /WEB-INF/applicationContext.xml для загрузки. После загрузки файлов контекста Spring создает объект WebApplicationContext на основе определений бинов и хранит его в ServletContext веб-приложения.

Все веб-фреймворки Java построены на основе Servlet API, поэтому вы можете использовать следующий фрагмент кода для получения доступа к этому "бизнес-контексту" ApplicationContext, созданному ContextLoaderListener.

В следующем примере показано, как получить WebApplicationContext:

WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

Класс WebApplicationContextUtils предназначен для удобства, поэтому вам не требуется запоминать имя атрибута ServletContext. Его метод getWebApplicationContext() возвращает null, если объект под ключом WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE не существует. Чтобы избежать получения NullPointerExceptions в вашем приложении, лучше использовать метод getRequiredWebApplicationContext(). Этот метод генерирует исключение, если отсутствует ApplicationContext.

Получив ссылку на WebApplicationContext, можно получать бины по их имени или типу. Большинство разработчиков получают бины по имени, а затем приводят их к одному из реализованных интерфейсов.

К счастью, большинство фреймворков, описанных в этом разделе, имеют более простые способы поиска бинов. Они не только упрощают получение бинов из контейнера Spring, но и позволяют использовать внедрение зависимостей в их контроллерах. В каждом разделе веб-фреймворка более подробно описаны конкретные стратегии интеграции.

JSF

JavaServer Faces (JSF) – это стандартный компонентный, событийно-ориентированный фреймворк пользовательского веб-интерфейса, разработанный в рамках процесса JCP. Он является официальной частью обобщенной спецификации Java EE, но также может использоваться отдельно, например, путем встраивания Mojarra или MyFaces в Tomcat.

Обратите внимание, что последние версии JSF стали тесно связаны с инфраструктурой CDI в серверах приложений, и некоторые новые функции JSF работают только в таком окружении Средства поддержки JSF в Spring больше активно не развиваются и главным образом применяются в целях миграции при модернизации старых приложений на базе JSF.

Ключевым элементом интеграции Spring с JSF является механизм ELResolver спецификации JSF.

5.2.1. Распознаватель бинов Spring

SpringBeanFacesELResolver – это реализация ELResolver, совместимая с JSF, интегрирующаяся со стандартным унифицированный языком выражений (Unified EL), используемым в JSF и JSP. Она делегирует полномочия сначала WebApplicationContext "бизнес-контекста" Spring, а затем распознавателю по умолчанию базовой реализации JSF.

С точки зрения конфигурации, можно определить SpringBeanFacesELResolver в файле faces-context.xml спецификации JSF, как показано в следующем примере:

<faces-config>
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
        ...
    </application>
</faces-config>

5.2.2. Использование FacesContextUtils

Кастомный ELResolver отлично работает при отображжении свойств на бины в faces-config.xml, но иногда может потребоваться явный захват бина. Класс FacesContextUtils облегчает эту задачу. Он похож на WebApplicationContextUtils, за исключением того, что принимает параметр FacesContext, а не ServletContext.

В следующем примере показано, как использовать FacesContextUtils:

ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

Apache Struts 2.x

Фреймворк Struts, придуманный Крейгом МакКланаханом, является проектом с открытым исходным кодом на базе Apache Software Foundation. В то время он значительно упростил парадигму программирования JSP/Servlet и покорил многих разработчиков, которые использовали проприетарные фреймворки. Он упрощал модель программирования, имел открытый исходный код (а значит, был бесплатным), и имел широкое сообщество, что позволяло проекту развиваться и быть популярным среди веб-разработчиков на Java.

В качестве преемника оригинального Struts 1.x, ознакомьтесь с Struts 2.x и предоставляемым в Struts плагином для Spring, предназначенным для встроенной интеграции со Spring.

Apache Tapestry 5.x

Tapestry – это "компонентно-ориентированный фреймворк для создания динамичных, надежных, масштабируемых веб-приложений на Java".

Хотя Spring и имеет свой собственный мощный веб-уровень, создание корпоративного Java-приложения с использованием комбинации из Tapestry для пользовательского веб-интерфейса и контейнера Spring для более низких уровней дает ряд уникальных преимуществ.

Для получения дополнительной информации см. специальный интеграционный модуль Tapestry для Spring.

Дополнительные источники

Следующие ссылки ведут на дополнительные источники, посвященные различным веб-фреймворкам, описанным в этой главе.

  • Домашняя страница JSF

  • Домашняя страница Struts

  • Домашняя страница Tapestry