В чем разница между аннотациями @Component и @Bean в Spring?

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

Ответ

Обе аннотации регистрируют объекты как бины в Spring-контейнере, но применяются в разных сценариях.

Критерий @Component (и ее стереотипы: @Service, @Repository, @Controller) @Bean
Уровень объявления Класс. Аннотация ставится непосредственно над классом. Метод. Аннотация ставится над методом в классе, помеченном @Configuration.
Контроль создания Создание и настройка управляются Spring'ом (через рефлексию). Создание и настройка полностью контролируются разработчиком в теле метода.
Использование для сторонних классов Невозможно, так как нужно модифицировать исходный код класса. Основной случай использования. Позволяет обернуть в бин класс из сторонней библиотеки, которым вы не управляете.
Название бина По умолчанию — имя класса с маленькой буквы. Можно задать в параметре: @Component("myName"). По умолчанию — имя метода. Можно задать в параметре: @Bean(name = "myName").

Примеры:

  1. @Component для собственного класса:

    @Component // Spring обнаружит и создаст бин типа MyService.
    public class MyService {
        // логика сервиса
    }
  2. @Bean для стороннего или сложного бина:

    @Configuration
    public class AppConfig {
    
        @Bean // Spring вызовет этот метод и зарегистрирует возвращаемый объект как бин.
        public DataSource dataSource() {
            // Полный контроль над созданием и конфигурацией
            HikariDataSource ds = new HikariDataSource();
            ds.setJdbcUrl("jdbc:h2:mem:test");
            ds.setUsername("sa");
            return ds;
        }
    
        @Bean("customBeanName")
        public MyBean myBean(MyService service) { // Зависимости можно инжектировать в параметры
            return new MyBean(service); // Создание с нестандартной логикой
        }
    }

Резюме: Используйте @Component для ваших собственных классов. Используйте @Bean в @Configuration-классах, когда нужно программно сконфигурировать бин (сторонняя библиотека, сложная инициализация, выбор реализации на лету).