В каких случаях требуется явное (ручное) объявление бина в Spring?

Ответ

Явное объявление бина в @Configuration классе необходимо, когда автоматического сканирования (@ComponentScan) недостаточно. Основные сценарии:

  1. Интеграция сторонних библиотек: Классы, исходный код которых нельзя аннотировать @Component.
  2. Кастомизация инстанса: Требуется тонкая настройка бина (параметры конструктора, свойства) перед внедрением в контекст.
  3. Условное создание: Бин должен создаваться только при определенных условиях (профиль, наличие свойства).

Пример конфигурации:

@Configuration
public class AppConfig {
    // 1. Кастомная настройка пула соединений
    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:h2:mem:test");
        ds.setMaximumPoolSize(10);
        return ds;
    }
    // 2. Условный бин для prod-среды
    @Bean
    @Profile("prod")
    public Service prodService() {
        return new ProdService();
    }
}

Явная конфигурация дает полный контроль, но увеличивает объем кода. Оптимально — гибридный подход.

Ответ 18+ 🔞

А, слушай, вот этот ваш @Configuration — это ж такая штука, когда ты сам, по-взрослому, говоришь Спрингу: «Слышь, дружок, не гадай тут на кофейной гуще, где там твои @ComponentScan-ы, я тебе сейчас всё сам, по кирпичику, соберу».

Ну, типа, зачем это надо, когда вроде бы всё и так автоматом должно находиться? А вот, блядь, случаи бывают:

  1. Сторонний код, который тебе не трогать. Ну, взял ты библиотеку какую-нибудь, там классы без твоих аннотаций @Component. И как его, сука, в контекст-то запихнуть? Вот тут ты его вручную объявляешь, как бин, и всё — он твой, в рот меня чих-пых!

  2. Настройка под микроскопом. Автоматом создастся — и хуй с ним. А тебе надо, чтоб именно вот с такими параметрами, чтоб пул соединений на 10 потоков, а не на 5, и URL базы вот такой. Тут ты разворачиваешься во всей красе, создаёшь инстанс, накручиваешь на него всё, что надо, и возвращаешь. Полный контроль, ёпта!

  3. Условные игры. Создавать бин, только если, например, профиль prod активен. Или если какое-то свойство в application.yml стоит. А то нафиг в тестах этот тяжёлый сервис для прода, который пол-оперативки жрёт?

Смотри, как это выглядит, на примере:

@Configuration
public class AppConfig {
    // 1. Вот пул соединений кастомный, чтоб всё чётко было
    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:h2:mem:test");
        ds.setMaximumPoolSize(10);
        return ds;
    }
    // 2. А этот сервис — только для прода, чтоб в других местах не маячил
    @Bean
    @Profile("prod")
    public Service prodService() {
        return new ProdService();
    }
}

Короче, явная конфигурация — это власть. Но и писанины, блядь, до овердохуища. Поэтому умные люди мешают: что-то автоматом, а что-то — вот так, вручную, в @Configuration. И живут спокойно, без лишней ебалы.