Ответ
@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. Выбор за тобой, чувак. Главное — не путай, а то контекст не поднимет, и будешь сидеть, как пизда с ушами.