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

Ответ

@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 — часть механизма автоматического сканирования компонентов.

Ответ 18+ 🔞

Ха, ну ты гонишь, конечно! Сравниваешь @Bean и @Component, как будто это одно и то же. Да нихуя, блядь! Это как сравнивать отвёртку и шуруповёрт — вроде оба крутят, но возможности, сука, овердохуища разные.

Смотри, разжую на пальцах, чтобы даже мартышлюшка поняла.

@Component (и его братва @Service, @Repository, @Controller) Это ты, такой красавчик, пишешь свой класс и сверху лепишь аннотацию. Spring, как хитрая жопа, сканирует проект, видит её и говорит: «О, новенький! Давай-ка я тебя сам создам через рефлексию, вызову твой конструктор и засуну в свой контекст». Всё, ты пассивный участник процесса.

@Component // Воткнул и забыл, как будто флаг поставил.
public class MyService {
    // Spring сам всё сделает, блядь
}

@Bean А вот это уже твой полный контроль, ебать мои старые костыли! Ты берёшь класс конфигурации (@Configuration) и внутри метода, который ты сам написал, создаёшь объект как бог на душу положит. Хочешь — через new, хочешь — фабричным методом, хочешь — перед возвратом ещё танцы с бубном устроишь. Spring просто вызовет твой метод и возьмёт то, что ты ему отдал.

@Configuration
public class AppConfig {

    @Bean // Тут я царь и бог, блядь!
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource(); // Сторонняя библиотека, её не аннотируешь!
        ds.setJdbcUrl("jdbc:h2:mem:test");
        ds.setMaximumPoolSize(10);
        // Вот тут я мог бы ещё проверки нахуярить, логи добавить...
        return ds; // На, Spring, жри!
    }
}

Так когда что использовать, чтобы не быть полупидором?

  • @Component — когда класс твой, и создать его просто: вызвал конструктор — и всё, пиздец. Коротко и декларативно.
  • @Bean — когда логика создания — пиздопроебибна (условия, циклы, сборка из кусков) или когда класс чужой (из библиотеки). Тут только @Bean спасёт, иначе нихуя не получится.

Итог, блядь: Это не синонимы, ёпта! @Component — это наклейка «создай меня» на своей коробке. @Bean — это твои руки, которыми ты из любого говна и палок можешь собрать объект и запихнуть его в Spring. Выбор за тобой, чувак. Главное — не путай, а то контекст не поднимет, и будешь сидеть, как пизда с ушами.