Получить доступ

Чем @Component отличается от @Bean?

MiddleСтереотипы и автосвязываниеSpring
Ещё спрашивают так:
  • Когда использовать @Bean, а когда @Component?
Коротко

@Component — на своём классе, бин находится сканированием. @Bean — на методе в @Configuration-классе, который создаёт и настраивает объект; подходит для чужих классов и сложной конструкции.

  • @Bean для библиотечных классов (ObjectMapper, RestClient, DataSource), которые нельзя пометить аннотацией
  • @Bean — несколько бинов одного класса с разной настройкой
  • @Service, @Repository, @Controller — специализации @Component

А ещё В @Configuration (proxyBeanMethods=true) вызов одного @Bean-метода из другого возвращает тот же singleton

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

@Component ставится на класс. При сканировании пакетов (@ComponentScan, по умолчанию от пакета @SpringBootApplication) Spring находит класс и регистрирует бин. Конструктор выбирается контейнером, все параметры — бины. Специализации: @Service, @Repository (с трансляцией исключений), @Controller/@RestController.

@Bean ставится на метод в классе с @Configuration. Метод сам создаёт и настраивает объект; его параметры — бины. Нужен, когда:

  • класс из библиотеки, и аннотацию на него не поставить;
  • нужна нетривиальная настройка (билдеры, условия);
  • нужно несколько бинов одного типа с разной конфигурацией (два DataSource).

Особенность @Configuration. По умолчанию класс проксируется CGLIB (proxyBeanMethods = true): вызов dataSource() из другого @Bean-метода вернёт существующий singleton, а не создаст новый. В «lite»-режиме (@Configuration(proxyBeanMethods = false) или @Bean в @Component) такой вызов — обычный вызов метода и создаст новый объект; Spring Boot использует lite-режим в автоконфигурациях ради скорости старта.

Что хотят услышать

  • Где ставится каждая аннотация и как находится бин.
  • Когда нужен @Bean.
  • Специализации @Component.
  • Проксирование @Configuration — плюс.

Частые ошибки

  • Пытаться поставить @Component на библиотечный класс.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗@Component для чужих классов, @Bean для своих
  • ✗Это одно и то же
  • ✓@Component — на своём классе (через component-scan); @Bean — метод в @Configuration для чужого/библиотечного класса
  • ✗@Bean можно ставить только на интерфейс

Что спросят дальше

  • Что делает @Configuration?
  • Как зарегистрировать сторонний класс как бин?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем