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

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

2.2 Middle🔥 111 комментариев
#Spring Framework

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

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

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

Области видимости (Scopes) Bean в Spring Framework

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

1. Singleton (по умолчанию)

Самый часто используемый scope. Контейнер создает один экземпляр бина на все приложение и переиспользует его:

@Component
public class UserService {
    // Singleton по умолчанию
}

// Или явно:
@Bean
@Scope("singleton")
public UserService userService() {
    return new UserService();
}

Характеристики:

  • Один экземпляр на контекст приложения
  • Потокобезопасный доступ требует внимания (может быть конкурентный доступ)
  • Эффективен по памяти

Когда использовать: для stateless сервисов (UserService, DatabaseService)

2. Prototype

Контейнер создает новый экземпляр каждый раз при запросе:

@Component
@Scope("prototype")
public class RequestData {
    // Новый экземпляр при каждом запросе
}

Характеристики:

  • Новый объект на каждый запрос
  • Не переиспользуется
  • Каждый объект имеет собственное состояние

Когда использовать: для stateful объектов, которые хранят данные конкретного запроса

3. Request

Для веб-приложений. Контейнер создает новый бин для каждого HTTP запроса:

@Component
@Scope("request")
public class HttpRequestData {
    // Живет во время одного HTTP запроса
}

Характеристики:

  • Один экземпляр на HTTP запрос
  • Автоматически уничтожается после завершения запроса
  • Доступен только в веб-контексте

Когда использовать: для данных, специфичных для одного HTTP запроса

4. Session

Для веб-приложений. Контейнер создает новый бин для каждой HTTP сессии:

@Component
@Scope("session")
public class UserSession {
    private User currentUser;
    // Живет во время сессии пользователя
}

Характеристики:

  • Один экземпляр на HTTP сессию
  • Сохраняется между запросами одного пользователя
  • Уничтожается при завершении сессии

Когда использовать: для данных о текущем пользователе, предпочтения

5. Application (ServletContext)

Один бин на весь сервлет контекст приложения:

@Component
@Scope("application")
public class ApplicationConfig {
    // Один экземпляр на приложение
}

Когда использовать: для глобальной конфигурации приложения

6. WebSocket

Один бин на WebSocket сессию (Spring 4.0+):

@Component
@Scope("websocket")
public class WebSocketHandler {
    // Один экземпляр на WebSocket соединение
}

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

// UserService — Singleton (stateless)
@Service
public class UserService {
    private final UserRepository userRepository;
    
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

// RequestData — Request scope (stateful)
@Component
@Scope("request")
public class RequestContext {
    private String requestId = UUID.randomUUID().toString();
    private long startTime = System.currentTimeMillis();
    
    public void logRequest() {
        System.out.println("Request: " + requestId + ", Time: " + startTime);
    }
}

// UserCart — Session scope
@Component
@Scope("session")
public class ShoppingCart {
    private List<Product> items = new ArrayList<>();
    
    public void addItem(Product product) {
        items.add(product);
    }
}

Таблица сравнения

ScopeКол-во экземпляровЖизненный циклПотокобезопасность
Singleton1 на приложениеПриложениеТребует синхронизации
Prototype1 на каждый запросКаждый запросБезопасен
Request1 на HTTP запросHTTP запросБезопасен
Session1 на сессиюСессияБезопасен

Важные моменты

  • Singleton автоматический: не указываете scope = используется singleton
  • Потокобезопасность: singleton бины будут вызваны из разных потоков
  • Dependency Injection: можно инжектить бины разных скоупов (с ограничениями)
  • ProxyMode: для инжекции prototype в singleton используйте proxyMode = ScopedProxyMode.TARGET_CLASS
@Bean
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Prototype prototypeBean() {
    return new Prototype();
}
Какие знаешь области видимости Bean? | PrepBro