Spring, можно ли определиться с @Primary внутри метода @Bean - PullRequest
0 голосов
/ 27 февраля 2020

Использование Springboot2 и java8.

У меня есть класс @Configuration, который будет создавать экземпляр компонента в зависимости от некоторых свойств, и в зависимости от этих свойств экземпляр компонента должен быть основным или нет.

@Configuration
public class MyConfClass {

    @Autowired
    private MyProperties myProperties;


    @Bean
    @ConditionalOnProperty(name = "property.use-default", havingValue = "false", matchIfMissing = true)
    public MySpringBean buildMySpringBean() {
        MySpringBean bean = new MySpringBean();
        if (myProperties.isPrimary()) {
           // Should be primary like if annotated with @Primary
        } else {
           // should not
        }
        return bean;
    }
}

1 Ответ

0 голосов
/ 27 февраля 2020

В общем, вы можете попытаться создать свой собственный BeanFactoryPostProcessor, который установит для параметра Primary определение бина на основе конфигурации, однако это означает, что вы погрузитесь довольно глубоко во внутренние пружины.

Если Вы не хотите возиться с этой довольно продвинутой концепцией,

Вероятно, вы можете go при следующем подходе:

@Configuration
public class MyConfClass {

    @Bean
    @Primary
    @ConditionalOnProperty(name = "shouldBeDefault", havingValue = "true", matchIfMissing = true)
    public MySpringBean buildMySpringBeanPrimary() {
        return new MySpringBean();
    }

    @Bean
    @ConditionalOnProperty(name = "shouldBeDefault", havingValue = "false", matchIfMissing = false)
    public MySpringBean buildMySpringBeanNotPrimary() {
        return new MySpringBean();
    }

Честно говоря, я не понял, что такое свойство property.use-default , но если вам также необходимо зависеть от этого условия, то, вероятно, вам придется подготовить «составное условие», которое будет оцениваться как «истина», только если оба «базовых» условия выполняются.

Это может сделать это легко, как объяснено Здесь

Обновление

Поскольку похоже, что вы собираетесь использовать BeanFactoryPostProcessor здесь, это пример это должно работать (возможно, с небольшими изменениями):

@Component // or register it in @Configuration as if its a regular bean
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  private final Environment env;

  public MyBeanFactoryPostProcessor(Envrionment env) {this.env = env;}

  public void postProcessBeanFactory(ConfiguratbleListableBeanFactory beanFactory) throws BeansException {

      boolean shouldBePrimary = resolveShouldBePrimary();

      if(shouldBePrimary) {
        BeanDefinition bd = beanFactory.getBeanDefinition("yourBeanName");
        bd.setPrimary(true);
      }            
   }

   private boolean resolveShouldBePrimary() {
      // here you can read properies directly or if you work with @ConfigurationProperties annotated class you can do:
      MyConfigProperties myConfigProperties = Binder.get(env).bind("prefix.in.config", MyConfigProperties.class).get()
      // now resolve from the mapped class     
   }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...