В чем разница между аннотациями @Bean и @Component в Spring и когда их можно использовать взаимозаменяемо?

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

Ответ

@Bean и @Component — это два разных способа регистрации бинов в контексте Spring, с разной областью применения.

Критерий @Component (и его стереотипы: @Service, @Repository, @Controller) @Bean
Уровень объявления Аннотация класса. Аннотация метода внутри класса, помеченного @Configuration.
Контроль над созданием Spring создает бин, вызывая конструктор (через рефлексию). Разработчик полностью контролирует логику создания объекта в методе.
Использование для сторонних классов Невозможно, если нельзя добавить аннотацию к исходному коду. Идеально подходит, так как метод может инстанцировать любой объект.

Пример @Component:

@Component // Spring обнаружит и создаст бин типа MyService
public class MyService {
    public void doWork() { ... }
}

Пример @Bean:

@Configuration
public class AppConfig {

    @Bean // Spring вызовет этот метод и зарегистрирует возвращаемый объект как бин
    public MyService myService() {
        return new MyService(); // Можно добавить любую логику создания
    }

    @Bean
    public DataSource dataSource() {
        // Создание бина из сторонней библиотеки (например, HikariCP)
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:h2:mem:test");
        return ds;
    }
}

Когда можно условно заменить одно другим?

  • Если у вас есть доступ к исходному коду класса и его создание простое (через конструктор), используйте @Component — это декларативнее и короче.
  • Если создание бина требует сложной логики (построение графа объектов, условная логика, вызов фабричных методов) или класс из сторонней библиотеки, используйте @Bean.

Важно: Они не являются полными синонимами. @Bean более гибкий и мощный инструмент для конфигурации, в то время как @Component — часть механизма автоматического сканирования компонентов.