Области видимости request
, session
, application
и websocket
доступны, только если вы используете реализацию ApplicationContext
в фреймворке Spring с поддержкой веб (например, XmlWebApplicationContext
). Если вы используете эти области видимости с обычными IoC-контейнерами Spring, такими как ClassPathXmlApplicationContext
, будет сгенерирован IllegalStateException
c сообщением о неизвестной области видимости бина.
Начальная веб-конфигурация
Для поддержки создания области видимости бинов на уровне request
, session
, application
и websocket
(web-scoped бины) перед определением бина требуется провести небольшую начальную настройку. (Данная начальная настройка не требуется для стандартных областей видимости: singleton
и prototype
).
То, каким образом вы выполните эту начальную настройку, зависит от вашей конкретной среды сервлетов.
Если вы обращаетесь к бинам, находящимся в области видимости, в Spring Web MVC, то есть в рамках запроса, который обрабатывается Spring DispatcherServlet
, никакой специальной настройки не требуется. DispatcherServlet
уже раскрывает все соответствующие состояния.
Если вы используете веб-контейнер Servlet 2.5, в котором запросы обрабатываются вне Spring DispatcherServlet
(например, при использовании JSF или Struts), вам необходимо зарегистрировать org.springframework.web.context.request.RequestContextListener ServletRequestListener
. Для Servlet 3.0+ это можно сделать программно, используя интерфейс WebApplicationInitializer
. В качестве альтернативы или для более старых версий контейнеров добавьте следующее объявление в файл web web.xml
вашего веб-приложения:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
В качестве альтернативы, если есть проблемы с настройкой слушателя, рассмотрите возможность использования RequestContextFilter
в Spring. Отображение фильтров зависит от окружающей конфигурации веб-приложения, поэтому вы должны изменить его соответствующим образом. В следующем листинге показана часть фильтра веб-приложения:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
DispatcherServlet
, RequestContextListener
и RequestContextFilter
делают одно и то же, а именно связывают объект HTTP-запроса с Thread
, который обслуживает этот запрос. Это позволяет получить доступ к бинам, входящим в область видимости request или session, далее по цепочке вызовов.
Область видимости request
Рассмотрим следующую XML-конфигурацию для определения бина:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
Контейнер Spring создает новый экземпляр бина LoginAction
с помощью определения бина loginAction
для каждого HTTP-запроса. То есть бин loginAction
находится в области видимости на уровне HTTP-запроса. Можно сколько угодно изменять внутреннее состояние создаваемого экземпляра, поскольку другие экземпляры, созданные на основе того же определения бина loginAction
, не видят этих изменений состояния. Они зависят от конкретного запроса. Если запрос завершает обработку, бин, находящийся в области видимости запроса, исключается.
При использовании компонентов, управляемых аннотациями, или конфигурации Java, аннотацию @RequestScope
можно использовать для назначения компонента области видимости request
. В следующем примере показано, как это сделать:
@RequestScope
@Component
public class LoginAction {
// ...
}
@RequestScope
@Component
class LoginAction {
// ...
}
Область видимости в пределах сеанса
Рассмотрим следующую XML-конфигурацию для определения бина:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Контейнер Spring создает новый экземпляр бина UserPreferences
с помощью определения бина userPreferences
на время жизни одной HTTP Session
. Иными словами, бин userPreferences
эффективно располагается в области видимости на уровне HTTP Session
. Как и в случае с бинами, находящимися в области видимости request, вы можете изменять внутреннее состояние созданного экземпляра сколько угодно, зная, что другие экземпляры HTTP Session
, которые также используют экземпляры, созданные на основе того же определения бина userPreferences
, не заметят этих изменений состояния, поскольку они относятся к отдельной HTTP Session
. Если HTTP Session
в конечном итоге исключается, бин, который привязан к этой конкретной HTTP Session
, также исключается.
При использовании компонентов, управляемых аннотациями, или конфигурации Java можно использовать аннотацию @SessionScope
, чтобы назначить компонент области видимости session
.
@SessionScope
@Component
public class UserPreferences {
// ...
}
@SessionScope
@Component
class UserPreferences {
// ...
}
Область видимости в пределах приложения
Рассмотрим следующую XML-конфигурацию для определения бина:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Контейнер Spring создает новый экземпляр бина AppPreferences
, используя определение бина appPreferences
единожды для всего веб-приложения. То есть бин appPreferences
находится в области видимости на уровне ServletContext
и хранится как обычный атрибут ServletContext
. Он в некоторой степени похож на бин-одиночку Spring, но отличается от него двумя важными особенностями: Он является объектом-одиночкой для каждого ServletContext
, а не для Spring ApplicationContext
(которых может быть несколько в любом конкретном веб-приложении), и он фактически открывается, поэтому и виден как атрибут ServletContext
.
При использовании компонентов, управляемых аннотациями, или конфигурации Java можно использовать аннотацию @ApplicationScope
для назначения компонента области видимости application
. В следующем примере показано, как это сделать:
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
@ApplicationScope
@Component
class AppPreferences {
// ...
}
Область видимости в пределах WebSocket
Область видимости WebSocket связана с жизненным циклом сессии WebSocket и применяется к приложениям STOMP over WebSocket.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ