Какой паттерн проектирования используется для создания бинов в Spring?

Ответ

Основным паттерном для создания бинов в Spring является Factory Method. Контейнер Spring выступает в роли фабрики, которая инстанцирует и управляет объектами (бинами) на основе конфигурации.

Почему Factory Method? Контейнер не использует оператор new напрямую в клиентском коде. Вместо этого он вызывает фабричные методы (помеченные @Bean или определенные в XML), которые инкапсулируют логику создания объекта.

Пример:

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        // Spring вызовет этот фабричный метод
        return new MyServiceImpl(dependency());
    }

    @Bean
    public Repository repository() {
        return new JdbcRepository(dataSource());
    }
}

Другие задействованные паттерны:

  • Singleton — область видимости бина по умолчанию. Контейнер возвращает один и тот же экземпляр.
  • Prototype — при каждом запросе создается новый экземпляр (задается аннотацией @Scope("prototype")).
  • Dependency Injection — паттерн, используемый для внедрения зависимостей, созданных фабрикой, в другие бины.

Ответ 18+ 🔞

А, слушай, вот это тема, про которую можно сломать мозг, если не понимать, с какого бока подойти. Представь себе такую картину: ты приходишь в огромный, ебаный, автоматизированный завод по производству... да чего угодно! Деталей, машин, пирожков. Ты не стоишь у конвейера с паяльником и не лепишь тесто руками. Ты — главный инженер, который нажимает одну хитрую кнопку «ПУСК» и говорит: «Хочу вот этот сервис, и чтобы к нему этот репозиторий был прикручен, а тот, в свою очередь, тыкался в базу данных вот этой конфигурации».

И завод (наш Spring-контейнер, блядь) тебе всё это делает. А как он делает? По какому принципу? А по принципу, ёпта, Фабричного Метода (Factory Method). Это и есть его основной, фундаментальный, ебучерский паттерн.

А почему именно он, а не просто new? Да потому что если бы ты везде сам писал new MyServiceImpl(), это был бы пиздец, а не архитектура. Ты бы сам стал этой фабрикой, только кривой и косой. А тут контейнер берёт на себя роль этой самой фабрики-завода. Ты ему не говоришь «создай объект». Ты ему говоришь: «Вот тебе рецепт (метод, помеченный @Bean), как его создавать. А когда надо — ты сам этот рецепт выполнишь и дашь мне готовую хуйню». Всё инкапсулировано, блядь. Красота!

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

@Configuration
public class AppConfig {
    @Bean
    public MyService myService() {
        // Spring, когда надо, вызовет этот метод — вот он, фабричный метод!
        return new MyServiceImpl(dependency());
    }

    @Bean
    public Repository repository() {
        return new JdbcRepository(dataSource());
    }
}

Видишь? Ты не создаешь myService руками. Ты объявляешь: «Слушай, заведение, вот способ, как его печь». А Spring уже сам, в нужный момент, подойдет к этому методу, вызовет его и получит бин. Фабрика, сука, в чистом виде!

Ну и вокруг этого основного паттерна уже пляшут другие, без них никуда:

  • Singleton (Одиночка) — это вообще дефолтная повадка Spring. Ты запросил бин — тебе выдали один и тот же экземпляр, который уже где-то валяется. Экономия памяти, ебать её в рот. Хоть сто раз запрашивай.
  • Prototype (Прототип) — полная противоположность. Сказал @Scope("prototype") — и будь добр, на каждый чих создавай новый, свеженький объект. Как сироту казанскую.
  • Dependency Injection (Внедрение зависимостей) — а это, можно сказать, логистика нашего завода. Фабрика (Spring) не только создала детали (бины), но и сама, блядь, понимает, какую куда вкрутить. Не надо тебе тащить repository в service руками — Spring сам его принесёт и вставит куда надо. Удобно, ёптель-моптель!

Вот и вся магия. Не оператором new единым, а фабричным методом, вокруг которого построена вся эта охуенно сложная, но работающая экосистема.