Что делает весенняя аннотация @ConditionalOnMissingBean?

Я пытаюсь запустить приложение springboot, в котором использовалась эта аннотация. Когда я пытаюсь запустить приложение, появляется следующая ошибка:

org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanTypeDeductionException Failed to deduce bean type for com.shutterfly.sbs.platform.SbsPlatformConfigurationClientConfig.getRestTemplate

Код:

@ConditionalOnMissingBean
@Bean
public RestTemplate getRestTemplate() {
    return new RestTemplate();
}

Он инициализирует bean-компонент только в том случае, если он не может найти bean-компонент RestTemplate в своем контексте. Если у него уже есть bean-компонент RestTemplate, он пропустит это.

pvpkiran 11.06.2018 13:43

Спасибо @pvpkiran

Ravi Wadje 11.06.2018 13:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
26
2
25 704
4

Ответы 4

Аннотация @ConditionalOnMissingBean - это условная аннотация Spring для регистрации bean-компонентов, только если они еще не находятся в контексте приложения.

См. Документацию: https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/api/org/springframework/boot/autoconfigure/condition/ConditionalOnMissingBean.html

Мы используем @ConditionalOnMissingBean, если хотим включить компонент, только если указанный компонент отсутствует. Например,

Давайте настроим bean-компонент transactionManager, который будет загружаться только в том случае, если bean-компонент типа JpaTransactionManager еще не определен:

@Bean
@ConditionalOnMissingBean(type = "JpaTransactionManager")
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory);
    return transactionManager;
}

Чтобы понять больше, рассмотрите также этот сценарий.

Допустим, в моем проекте я настроил bean-компонент videoDecoderService

@Bean
@ConditionalOnMissingBean(VideoDecoderService.class)
public videoDecoderService videoDecoderService(){
return new VideoDecoderService;
}

Что он будет делать, так это то, что тот, кто использует мой проект, сможет заменить videoDecoderService собственным videoDecoderService. Если они не пишут свой собственный videoDecoderService, то будет предоставлен этот @ConditionalOnMissingBean по умолчанию.

Аннотация @ConditionalOnMissingBean используется для загрузки bean-компонента, только если данный bean-компонент отсутствует:

@Bean
@ConditionalOnMissingBean(SomeBean.class)
public SomeBean otherBean(){
    return new SomeBean();
}

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

Некоторые варианты использования, в которых может пригодиться эта аннотация:

  • Указание резервного bean-компонента, который загружается только в качестве резервной копии, если нет bean-компонента того же типа (например: использование базы данных в памяти, если не настроена реальная база данных)
  • Указание bean-компонента по умолчанию, который позволяет переопределить в случае, если в контексте присутствует более конкретный bean-компонент того же типа (например: с использованием механизма аутентификации по умолчанию, если кто-то не решит заменить его собственной пользовательской аутентификацией)

Ссылка: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html

будьте осторожны с порядком, в котором добавляются определения bean-компонентов, так как эти условия оцениваются на основе того, что было обработано до сих пор (из Spring doc)

Abhishek Chatterjee 23.05.2020 14:48

Вы не должны пропускать ту часть документации, в которой четко сказано:

The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only.

Позже будет сказано:

If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after

Проще говоря, это может означать, что @Bean, вызванный некоторой автоконфигурацией Другие, должен иметь приоритет над тем, который вы определили. Чтобы это работало, вам необходимо правильно настроить порядок этих конфигураций через @AutoConfigureBefore.

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