Какой scope у бина, объявленного с аннотацией @Component, если не указан явно?

«Какой scope у бина, объявленного с аннотацией @Component, если не указан явно?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Бин, объявленный с помощью @Component (или ее специализаций: @Service, @Repository, @Controller), по умолчанию имеет scope singleton.

Объяснение: Spring контейнер создает один единственный экземпляр такого бина на все приложение. Этот экземпляр кэшируется, и все последующие запросы к этому бину получают один и тот же объект.

Пример:

@Component // Неявно @Scope("singleton")
public class ShoppingCartService {
    private List<Item> items = new ArrayList<>();
    // Это поле будет общим для всех клиентов, использующих этот бин,
    // что обычно является ошибкой дизайна для такого сервиса.
}

Как проверить или изменить:

  1. Проверить: Можно инжектировать бин в два разных места и сравнить ссылки (==). Они будут одинаковыми.
  2. Изменить: Явно указать другую область видимости с помощью аннотации @Scope.
    @Component
    @Scope("prototype") // Теперь при каждом инжекте будет новый экземпляр
    public class PrototypeComponent { }

Важно: Для stateful-бинов, хранящих данные конкретного пользователя или запроса (как ShoppingCartService в примере), singleton scope не подходит. В таких случаях следует использовать request или session scope, либо полностью избегать хранения состояния в бине.