Как Spring обрабатывает bean-компоненты при использовании в другом методе в том же файле конфигурации

Я пытаюсь разобраться в инициализации bean-компонентов Spring на основе аннотаций. Итак, у меня есть класс, в котором есть несколько объявлений bean-компонентов, и некоторые bean-компоненты требуются другим bean-компонентам. У меня возникает вопрос: если бы я напрямую использовал метод bean-компонента в другом методе bean-фабрики, Spring правильно обработал бы его и внедрил требуемый bean-компонент, или в конечном итоге я создал бы несколько экземпляров внедренного bean-компонента?

Образец кода

@Configuration
class Config {
    
    @Bean
    public SomeBean someBean() {
        // some builder code
        return someBean;
    }

    @Bean
    public AnotherBean anotherBean() {
        return anotherBeanBuilder
            .withSomeBean(someBean())
            .build();
    }
}

Итак, если я перефразирую свой вопрос на основе приведенного выше примера, я хочу знать, что, по сути, когда я использую anotherBean() в каком-то другом месте, Spring будет правильно использовать уже созданный someBean или в конечном итоге создаст несколько экземпляров SomeBean.

Да, это так. Но лучше просто внедрить компонент в метод в качестве аргумента, поскольку это облегчит Spring определение зависимостей между компонентами и обеспечит правильный порядок установки.

M. Deinum 06.03.2024 20:01

Иногда у вас нет выбора, например, в некоторых конфигураторах, таких как SpringMVC или Spring Security. Если у вас есть выбор, поступайте так, как предлагает @M.Deinum.

Chasca 06.03.2024 20:29

Spring MVC ничего подобного не предотвращает, равно как и Spring Security (особенно новая версия конфигурации).

M. Deinum 06.03.2024 20:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Spring создает специальные прокси для классов @Configuration. Фактически метод вызывается только один раз. Проверить свою гипотезу самостоятельно довольно легко:

@Configuration
class Config {
    
    @Bean
    public SomeBean someBean() {
        final SomeBean bean;
        System.out.println("created someBean: " + bean);
        return bean;
    }

    @Bean
    public AnotherBean anotherBean() {
        System.out.println(someBean()); // SomeBean@cafe0420 (example)
        System.out.println(someBean());
        System.out.println(someBean());
        return new AnotherBean(someBean());
    }
}

class SomeBean {}
class AnotherBean { AnotherBean(SomeBean bean) {} }

Выход:

created someBean: SomeBean@cafe0420
SomeBean@cafe0420
SomeBean@cafe0420
SomeBean@cafe0420

Итак, как вы можете видеть, вызов метода класса конфигурации вернет тот же один экземпляр компонента (на самом деле он вообще не вызывает метод).

Дополнительные ресурсы:

Другие вопросы по теме

Direct/Executor Channel — обходить некоторые пользовательские исключения в случае, если для стратегии аварийного переключения установлено значение true (не использовать других подписчиков)
Конфигурация безопасности Spring в application.yml, клиенте или сервере ресурсов?
Javax.net.ssl.SSLException: непредвиденная ошибка: java.security.InvalidAlgorithmParameterException
Ошибка сборки проекта: неразрешимый родительский POM: не удалось устранить следующие артефакты
Spring Cloud Stream Конфигурация нескольких кластеров Kafka
Настройка Spring Boot с помощью Docker Compose: выбор конкретной службы базы данных из нескольких служб
Как выполнить самостоятельное внедрение Spring Boot 3+, чтобы пройти через прокси и применить транзакционное поведение
Совет @AfterThrowing применяется дважды
Можете ли вы получить доступ к полям @Autowire'd через статические ссылки?
Службе требовался bean-компонент типа «Репозиторий», который не удалось найти в проекте Springboot