← Назад к вопросам

Какие знаешь области видимости бинов?

2.0 Middle🔥 131 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Области видимости бинов в Spring Framework

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

Стандартные (встроенные) области видимости

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

1. Singleton

Самый распространенный и default scope. Бин создается один раз на весь ApplicationContext, и каждый запрос к этому бину возвращает один и тот же экземпляр. Состояние бина является общим для всех клиентов.

@Component
@Scope("singleton") // или просто @Component без указания scope
public class SingletonService {
    private int counter = 0;
    public void increment() { counter++; }
    public int getCounter() { return counter; }
}
  • Плюсы: Экономия памяти, высокая производительность.
  • Минусы: Небезопасен в многопоточной среде без дополнительной синхронизации. Не подходит для состояния, специфичного для каждого клиента.

2. Prototype

Бин создается новый экземпляр при каждом запросе (через getBean() или инъекцию). Аналог паттерна "Фабрика". Идеально для объектов с независимым состоянием.

@Component
@Scope("prototype")
public class PrototypeProcessor {
    private UUID id = UUID.randomUUID(); // У каждого экземпляра уникальный ID
    public UUID getId() { return id; }
}
  • Плюсы: Полная независимость состояния, безопасность в многопоточной среде.
  • Минусы: Больший расход памяти и производительности на создание.

3. Request (Web-контекст)

Бин создается для каждого HTTP-request и уничтожается после завершения request. Используется для состояния, связанного с одним запросом (например, данные формы).

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    private String requestData;
    // Данные уникальны для каждого HTTP-запроса
}
  • Применение: Веб-контроллеры, обработка пользовательских данных.

4. Session (Web-контекст)

Бин создается для каждой HTTP-session пользователя и живет пока активна сессия. Подходит для пользовательских данных в течение всей сессии (например, корзина покупок).

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserSession {
    private List<CartItem> cartItems = new ArrayList<>();
    // Корзина сохраняется на протяжении всей сессии пользователя
}

5. Application (Web-контекст)

Бин создается один раз на весь ServletContext, что немного шире, чем singleton в Spring контексте, но похоже по концепции. Разница: Application scope виден всем Spring контекстам в одном веб-приложении.

6. WebSocket (Web-контекст)

Новый scope, добавленный в Spring 4. Бин создается для каждого WebSocket сеанса и живет в его пределах.

Как задать область видимости

  • Аннотации: @Scope("scopeName") на классе бина.
  • XML конфигурация: <bean id="..." class="..." scope="prototype"/>
  • Для веб-scopes часто требуется proxyMode: proxyMode = ScopedProxyMode.TARGET_CLASS (использует CGLIB прокси) или ScopedProxyMode.INTERFACES (JDK dynamic proxy). Это необходимо потому, что веб-scopes (request, session) короче жизни контейнера, и прокси обеспечивает инъекцию "правильного" экземпляра в момент выполнения.
@Configuration
public class AppConfig {
    @Bean
    @Scope("prototype")
    public MyBean myBean() {
        return new MyBean();
    }
}

Особенности и важные замечания

  • Singleton и Prototype — фундаментальные: Они работают в любом контексте Spring (не только веб).
  • Веб-scopes требуют контекста: Request, Session, Application, WebSocket доступны только в WebApplicationContext (например, Spring MVC).
  • Проксирование для короткоживущих scopes: Для инъекции бинов с более короткой жизнью (request, session) в бины с более длинной жизнью (singleton) Spring создает прокси-объект, который в момент обращения делегирует к реальному экземпляру текущего request/session.
  • Расширение через Custom Scope: Можно создать свою область видимости через интерфейс org.springframework.beans.factory.config.Scope и регистрацию в контексте. Например, scope "thread" для бина на время жизни потока.
  • Влияние на жизненный цикл: Методы @PostConstruct и @PreDestroy вызываются соответственно для каждого создания/уничтожения экземпляра в рамках его scope.

Практические примеры использования

  • Singleton: Сервисы, репозитории, компоненты без состояния (или с безопасным состоянием).
  • Prototype: Компоненты с тяжелой инициализацией, которые должны быть независимыми (например, обработчик задачи в пуле).
  • Request: Хранилище временных данных запроса в MVC.
  • Session: Авторизация пользователя, корзина покупок в e-commerce.

Выбор правильного scope напрямую влияет на корректность работы приложения, особенно в многопользовательских и многопоточных сценариях. Неправильное использование singleton для состояния пользователя может привести к смешению данных и серьезным ошибкам.

Какие знаешь области видимости бинов? | PrepBro