Ответ
Spring создает и регистрирует бин при обработке метода, помеченного @Bean, внутри класса с аннотацией @Configuration.
Процесс создания:
- Обнаружение: Контейнер Spring находит все классы, помеченные
@Configuration. - Обработка методов
@Bean: Для каждого метода с аннотацией@BeanSpring вызывает его, чтобы получить объект. - Проксирование (CGLIB): Классы
@Configurationпроксируются по умолчанию. Это гарантирует, что вызовы методов@Beanвнутри того же конфигурационного класса будут перенаправлены контейнеру, что позволяет сохранить семантику синглтона (метод будет вызван только один раз, а результат закэширован). - Регистрация: Возвращаемый объект регистрируется в контексте приложения как бин.
Пример и детали:
@Configuration
public class AppConfig {
@Bean // Имя бина по умолчанию — 'myService'
public MyService myService() {
// Этот метод будет вызван Spring'ом ровно один раз
return new MyServiceImpl();
}
@Bean(name = "customDataSource") // Явное указание имени бина
@Primary // Помечает бин как предпочтительный при внедрении по типу
public DataSource dataSource() {
return new HikariDataSource();
}
@Bean
@Scope("prototype") // Область видимости — новый экземпляр при каждом запросе
public TransactionalService transactionalService() {
return new TransactionalService();
}
}
Важные аспекты:
- Жизненный цикл: К бинам, созданным через
@Bean, применяются callback-методы жизненного цикла (@PostConstruct,@PreDestroy, интерфейсыInitializingBean,DisposableBean). - Внедрение зависимостей: Параметры метода
@Beanавтоматически рассматриваются как зависимости для внедрения.@Bean public OrderProcessor orderProcessor(MyService service, DataSource dataSource) { return new OrderProcessor(service, dataSource); } - Отличие от
@Component:@Beanпозволяет регистрировать как экземпляры собственных классов, так и экземпляры сторонних библиотек, код которых вы не можете аннотировать.