Gymterview
middle

Чем отличаются @Configuration и @Component? Что делает аннотация @Bean?

@Configuration – аннотация, указывающая, что класс содержит определения бинов (методы @Bean). @Bean – аннотация, помечающая метод как фабричный: возвращаемый объект регистрируется как бин в контейнере.

Ключевое отличие: класс с @Configuration обрабатывается через CGLIB-прокси, гарантируя, что вызовы методов @Bean внутри класса возвращают один и тот же singleton-экземпляр.

Пример
@Configuration
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }

    @Bean
    public UserRepository userRepository() {
        // dataSource() НЕ создаст новый объект,
        // а вернёт тот же singleton-бин благодаря CGLIB-прокси
        return new UserRepository(dataSource());
    }
}

Если использовать @Component вместо @Configuration:

Пример
@Component // БЕЗ CGLIB-прокси!
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }

    @Bean
    public UserRepository userRepository() {
        // ВНИМАНИЕ: dataSource() создаст НОВЫЙ экземпляр DataSource!
        return new UserRepository(dataSource());
    }
}

Это называется lite mode – методы @Bean вызываются как обычные Java-методы, без перехвата CGLIB.

На собеседовании: ключевое – CGLIB-прокси в @Configuration, который обеспечивает singleton-семантику при вызове @Bean-методов друг из друга. Частая ошибка – не знать про lite mode и разницу в поведении.