Определение бина с двумя возможными реализациями - PullRequest
0 голосов
/ 23 октября 2018

Пока у меня было очень простое определение bean-компонента, которое выглядело так:

@Bean
@Conditional(value=ConditionClass.class)
SomeInterface myMethodImpl(){
    return new ImplementationOne();
}

Однако теперь у меня есть ситуация, когда добавлен дополнительный класс реализации, назовем его ImplementationTwo, который требуетдля использования вместо ImplementationOne, когда опция включена в файле конфигурации.

Итак, мне нужно что-то вроде этого:

@Bean
@Conditional(value=ConditionClass.class)
SomeInterface myMethodImpl(){
    return context.getEnvironment().getProperty("optionEnabled") ? new 
   ImplementationOne() : new ImplementationTwo();
}

В основном способ создания правильной реализации в bean-компонентевремя определения на основе значения конфигурации.Возможно ли это и можно ли привести пример?Спасибо

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Это можно реализовать без использования @Conditional.

Предполагая, что у вас есть интерфейс SomeInterface и две реализации ImplOne ImplTwo:

SomeInterface.java

public interface SomeInterface {
    void someMethod();
}

ImplOne.java

public class ImplOne implements SomeInterface{
    @Override
    public void someMethod() {
       // do something
    }
}

ImplTwo.java

public class ImplTwo implements SomeInterface{
    @Override
    public void someMethod() {
       // do something else
    }
}

Затем вы можете контролировать, какая реализация используется в классе конфигурации следующим образом:

MyConfig.java

@Configuration
public class MyConfig {

    @Autowired
    private ApplicationContext context;

    @Bean
    public SomeInterface someInterface() {
        if (this.context.getEnvironment().getProperty("implementation") != null) {
            return new ImplementationOne();
        } else {
            return new ImplementationTwo();
        }
    }
}

Убедитесь, что компонент сканирования пружин находит MyConfig.Затем вы можете использовать @Autowired для внедрения правильной реализации где-либо еще в вашем коде.

0 голосов
/ 23 октября 2018

Я думаю, что вы делаете это неправильно.

Вы должны использовать @Conditional() в своей реализации, а не в интерфейсе.

Вот как я бы это сделал:

Интерфейс, который вы будете использовать в своем коде.

MyInterface.java

public interface MyInterface {
   void myMethod();
}

Первая реализация:

MyInterfaceImplOne.java

@Bean
@Conditional(MyInterfaceImplOneCondition.class)
public class MyInterfaceImplOne implements MyInterface {
   void myMethod(){
     // dosmthg
    }
}

MyInterfaceImplOneCondition.java

public class MyInterfaceImplOneCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
       return context.getEnvironment().getProperty("optionEnabled")
    }
}

И для 2-й реализации:

MyInterfaceImplTwo.java

@Bean
@Conditional(MyInterfaceImplTwoCondition.class)
public class MyInterfaceImplTwo implements MyInterface {
   void myMethod(){
     // dosmthg 2
    }
}

MyInterfaceImplTwoCondition.java

public class MyInterfaceImplTwoCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
       return !context.getEnvironment().getProperty("optionEnabled")
    }
}

InВ этом случае вам просто нужно вызвать интерфейс, и Spring введет компонент, соответствующий нужному условию.

Надеюсь, это то, что вы ищете, и я достаточно ясно!

...