Какие области видимости (scopes) бинов вы знаете в Spring Framework? Опишите каждый из них.java-8

В Spring Framework область видимости (scope) бина определяет его жизненный цикл и контекст, в котором он существует. Spring предоставляет несколько стандартных областей видимости, каждая из которых подходит для разных сценариев использования. Давайте рассмотрим каждую из них.

1. Singleton

Singleton — это область видимости по умолчанию в Spring. Бин с этой областью видимости создается один раз за время жизни контекста приложения, и один и тот же экземпляр возвращается при каждом запросе этого бина.

Пример:

@Component
@Scope("singleton")
public class SingletonBean {
    public SingletonBean() {
        System.out.println("SingletonBean создан");
    }
}

Особенности:

  • Один экземпляр на контекст: Все запросы к этому бину возвращают один и тот же экземпляр.
  • Потокобезопасность: Если бин не содержит изменяемого состояния, он безопасен для использования в многопоточной среде.
  • Использование: Подходит для stateless-бинов, таких как сервисы, репозитории и т.д.

2. Prototype

Prototype — это область видимости, при которой каждый запрос к бину создает новый экземпляр.

Пример:

@Component
@Scope("prototype")
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("PrototypeBean создан");
    }
}

Особенности:

  • Новый экземпляр при каждом запросе: Каждый раз, когда бин запрашивается из контекста, создается новый экземпляр.
  • Использование: Подходит для бинов, которые должны иметь собственное состояние или не должны быть разделяемыми между несколькими компонентами.

3. Request

Request — это область видимости, при которой бин создается для каждого HTTP-запроса. Эта область видимости используется в веб-приложениях.

Пример:

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestBean {
    public RequestBean() {
        System.out.println("RequestBean создан");
    }
}

Особенности:

  • Один экземпляр на запрос: Бин создается для каждого HTTP-запроса и уничтожается после завершения запроса.
  • Использование: Подходит для хранения данных, специфичных для одного запроса, например, данных формы.

4. Session

Session — это область видимости, при которой бин создается для каждой HTTP-сессии. Эта область видимости также используется в веб-приложениях.

Пример:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionBean {
    public SessionBean() {
        System.out.println("SessionBean создан");
    }
}

Особенности:

  • Один экземпляр на сессию: Бин создается для каждой HTTP-сессии и уничтожается после завершения сессии.
  • Использование: Подходит для хранения данных, специфичных для пользователя, например, корзины покупок.

5. Application

Application — это область видимости, при которой бин создается один раз на все приложение. Это похоже на Singleton, но бин доступен в контексте ServletContext.

Пример:

@Component
@Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ApplicationBean {
    public ApplicationBean() {
        System.out.println("ApplicationBean создан");
    }
}

Особенности:

  • Один экземпляр на приложение: Бин создается один раз и доступен в контексте ServletContext.
  • Использование: Подходит для хранения данных, которые должны быть доступны всем компонентам приложения.

6. WebSocket

WebSocket — это область видимости, при которой бин создается для каждого WebSocket-сеанса. Эта область видимости используется в приложениях, работающих с WebSocket.

Пример:

@Component
@Scope(value = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class WebSocketBean {
    public WebSocketBean() {
        System.out.println("WebSocketBean создан");
    }
}

Особенности:

  • Один экземпляр на WebSocket-сеанс: Бин создается для каждого WebSocket-сеанса и уничтожается после его завершения.
  • Использование: Подходит для хранения данных, специфичных для WebSocket-сеанса.

7. Custom Scope

Spring также позволяет создавать пользовательские области видимости, если стандартные не подходят для ваших нужд. Для этого нужно реализовать интерфейс Scope и зарегистрировать его в контексте.

Пример:

public class CustomScope implements Scope {
    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        // Логика получения бина
    }

    @Override
    public Object remove(String name) {
        // Логика удаления бина
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        // Логика регистрации callback
    }

    @Override
    public Object resolveContextualObject(String key) {
        // Логика разрешения контекстного объекта
    }

    @Override
    public String getConversationId() {
        // Логика получения идентификатора контекста
    }
}

Особенности:

  • Гибкость: Позволяет определить собственную логику жизненного цикла бинов.
  • Использование: Подходит для сложных сценариев, когда стандартные области видимости не подходят.

Резюмируем

  • Singleton: Один экземпляр на контекст приложения. Подходит для stateless-бинов.
  • Prototype: Новый экземпляр при каждом запросе. Подходит для бинов с собственным состоянием.
  • Request: Один экземпляр на HTTP-запрос. Используется в веб-приложениях.
  • Session: Один экземпляр на HTTP-сессию. Используется для хранения данных пользователя.
  • Application: Один экземпляр на приложение. Доступен в контексте ServletContext.
  • WebSocket: Один экземпляр на WebSocket-сеанс. Используется в приложениях с WebSocket.
  • Custom Scope: Позволяет создать пользовательскую область видимости. Подходит для сложных сценариев.

Выбор области видимости зависит от требований вашего приложения. Правильное использование областей видимости помогает управлять жизненным циклом бинов и оптимизировать использование ресурсов.