Какие области видимости (Scopes) бинов существуют в Spring Framework?

«Какие области видимости (Scopes) бинов существуют в Spring Framework?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Spring Framework предоставляет несколько встроенных областей видимости (Scopes) для бинов, которые определяют, как контейнер IoC создаёт и управляет экземплярами.

Стандартные Scopes (доступны в любом контексте):

  1. singleton (по умолчанию): Один экземпляр на контейнер Spring.
  2. prototype: Новый экземпляр при каждом запросе или инъекции.

Web-ориентированные Scopes (требуют конфигурации, например, web.xml или ServletWebServerApplicationContext):

  1. request: Экземпляр на HTTP-запрос.
  2. session: Экземпляр на HTTP-сессию пользователя.
  3. application: Экземпляр на ServletContext (шире, чем singleton, но в рамках веб-приложения).
  4. websocket: Экземпляр на жизненный цикл WebSocket-сессии.

Примеры объявления:

// 1. Singleton (явное указание или по умолчанию)
@Service // или @Scope("singleton")
public class DefaultService { /* один на всё приложение */ }

// 2. Prototype
@Repository
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeDao { /* новый при каждом внедрении */ }

// 3. Request Scope (в веб-приложении)
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    private String requestId = UUID.randomUUID().toString(); // Уникален для каждого запроса
}

// 4. Использование в контроллере
@RestController
public class MyController {
    @Autowired
    private RequestScopedBean requestBean; // Инжектится прокси, который на каждый запрос возвращает новый экземпляр
}

Ключевые отличия и практика:

  • Производительность: singleton — самый эффективный, создаётся один раз. prototype, request — создание объекта при каждом запросе.
  • Состояние: singleton бины не должны хранить состояние, специфичное для пользователя или запроса. Для этого используйте request или session scope.
  • Проксирование (proxyMode): Для web-скопов (request, session, application) часто требуется ScopedProxyMode.TARGET_CLASS, чтобы Spring мог внедрить "прокси", который будет разрешать реальный бин в момент выполнения (при каждом новом запросе/сессии).