Області видимості request, session, application та websocket доступні лише якщо ти використовуєш реалізацію ApplicationContext у фреймворку Spring із підтримкою веб (наприклад, XmlWebApplicationContext). Якщо ти використовуєш ці області видимості зі звичайними IoC-контейнерами Spring, такими як ClassPathXmlApplicationContext, буде згенеровано IllegalStateException з повідомленням про невідому область видимості біна.

Початкова вебконфігурація

Для підтримки створення області видимості бінів на рівні 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. У цьому прикладі показано, як це зробити:

Java
@RequestScope
@Component
public class LoginAction {
    // ...
}
Kotlin
@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.

Java
@SessionScope
@Component
public class UserPreferences {
    // ...
}
Kotlin
@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. У цьому прикладі показано, як це зробити:

Java
@ApplicationScope
@Component
public class AppPreferences {
    // ...
}
Kotlin
@ApplicationScope
@Component
class AppPreferences {
    // ...
}

Область видимості в межах WebSocket

Область видимості WebSocket пов'язана з життєвим циклом сесії WebSocket і застосовується до програм STOMP over WebSocket.