Какие основные способы объявления бинов существуют в Spring?

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

Ответ

Spring предлагает несколько ключевых способов объявления бинов, от аннотаций до программной конфигурации:

1. Аннотирование классов (Component Scanning)

Наиболее распространённый способ. Spring сканирует classpath и регистрирует классы, помеченные стереотипными аннотациями, как бины.

  • @Component — общая стереотипная аннотация.
  • @Service — для классов бизнес-логики.
  • @Repository — для классов доступа к данным (также перехватывает исключения доступа к данным).
  • @Controller / @RestController — для веб-контроллеров.
@Service
public class UserService {
    // Spring создаст бин с именем 'userService'
}

2. Java-based конфигурация (@Bean)

Используется в классах, помеченных @Configuration. Позволяет определять бины с помощью методов, что полезно для:

  • Конфигурации сторонних библиотек.
  • Сложной логики инициализации.
  • Условного создания бинов (@Conditional).
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // Создание и настройка DataSource
        return new HikariDataSource();
    }

    @Bean(name = "myBean") // Можно задать имя
    @Scope("prototype")     // И другие атрибуты
    public MyService myService() {
        return new MyService(dataSource());
    }
}

3. XML-конфигурация (Legacy)

Устаревший, но поддерживаемый способ. Бины объявляются в XML-файлах контекста.

<beans>
    <bean id="userRepository" class="com.example.UserRepositoryImpl"/>
    <bean id="userService" class="com.example.UserService">
        <property name="repository" ref="userRepository"/>
    </bean>
</beans>

4. Программная регистрация

Позволяет регистрировать бины напрямую в ApplicationContext.

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// Регистрация класса как бина
context.register(MyService.class);
// Регистрация через BeanDefinition
context.registerBean("customBean", MyBean.class, () -> new MyBean("param"));
context.refresh();

5. Фабрика бинов (FactoryBean)

Интерфейс для создания сложных объектов, логика создания которых не умещается в простой конструктор.

Выбор способа:

  • Для собственных классов — @Component и его производные.
  • Для конфигурации инфраструктуры или сторонних библиотек — @Bean в @Configuration классе.
  • Современные приложения используют комбинацию Component Scanning и Java-based конфигурации.