Как выбрать реализацию компонента во время выполнения для каждого http-запроса - PullRequest
0 голосов
/ 11 июня 2018

У меня есть две реализации моего компонента.

public interface MyComponent {

}

Imple1

@Component("impCompf")
@Lazy
@RequestScope
public class ImpComp1 implements MyComponent {

}

Imple2

@Component("impComps")
@Lazy
@RequestScope
public class ImpComp2 implements MyComponent {

}

Пока я создал два условия:

Imple1

public class FirstCondition implements Condition {

        @Override
    public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {        

        return staticVariable.contains("impCompf"); 
    }
}

То же самое относится к imple2

и определить configuration класс

@Configuration
public class MyConfiguration {
    @Bean
    @Conditional(FirstCondition .class)
    @Primary    
    public MyComponent getComp1() {
       return new ImpComp1();
    }

public static String staticVariable= "impCompf";

и в Моем основном controller:

@RequestMapping(value="api/{co}", method=RequestMethod.POST)
public ResponseEntity<Modelx> postSe(@PathVariable("co") String co) {
    if(co.contains("impCompf"))
        staticVariable = "impCompf";
    else (co.contains("impComps"))
        staticVariable = "impComps";

Что я хочу: длякаждый http запрос я хочу загрузить правильную реализацию

Но как бы то ни было, я получаю реализацию, определенную первой в статической переменной.

Если есть другая элегантная и лучшаяКстати, я хотел бы знать об этом.

1 Ответ

0 голосов
/ 11 июня 2018

Я думаю, здесь есть некоторая путаница относительно цели условий.Они не используются в момент поступления ваших запросов для автоматической передачи bean-компонента-кандидата в ваш контроллер.Они используются при запуске приложения для настройки контекста приложения на основе среды, пути к классам и т. Д. *

Нет необходимости в созданных вами условных классах.Это определяет конфигурацию bean-компонентов, когда контекст запускается, а не для каждого запроса во время выполнения.

Использование статической переменной также проблематично в сценарии с одним или несколькими одновременными запросами или в случаегде несколько потоков могут наблюдать разные значения, если только не используется какой-либо другой механизм в модели памяти Java (например, volatile или установление отношения перед событием, например, с sychnronized)

Существует несколько способовделать то, что вы пытаетесь достичь.Поскольку в конечном итоге вы, похоже, используете параметр пути, предоставленный клиентом, чтобы определить, какую службу вы хотите вызвать, вы можете использовать классический шаблон фабрики для возврата правильной реализации интерфейса на основе программного ввода строки.

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

Хотя, возможно,Как правило, рекомендуется также внедрить экземпляр контекста приложения и найти его в поиске соответствующего компонента по имени или классу: https://brunozambiazi.wordpress.com/2016/01/16/getting-spring-beans-programmatically/ - хотя это более громоздко, и вам нужно будет обрабатывать такие вещи, как org.springframework.beans.factory.NoSuchBeanDefinitionException иликастинг в некоторых случаях - лучше избегать в пользу одного из других методов.

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