Я пытаюсь реализовать что-то вроде «функции плагина» с помощью инъекции CDI. Но у меня возникли некоторые проблемы, и я подумал, что могу узнать мнение со стороны от моих товарищей «Стэкеров» :-)
Я дошел до того, что что-то вроде этого работает:
@Inject
@ScoringModule("AGE")
private AgeModule ageModule;
@Inject
@ScoringModule("CUSTOMER_TYPE")
private CustomerTypeModule customerTypeModule;
Когда я "запускаю" это, оба поля вводятся с соответствующими экземплярами. Но когда я пытаюсь ввести их немного более «динамично», вот так:
@Inject @Any
private Instance<CustomerScoringModule> scoringModuleInstance;
CustomerScoringModule module = scoringModuleInstance.select(new ScoringModuleLiteral("AGE")).get();
Тогда я получу такое исключение:
org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type CustomerScoringModule with qualifiers @Any @ScoringModule
Мне это кажется странным, потому что CDI явно «знает» об интересующих меня экземплярах, потому что работает прямая инъекция в типизированные поля. Я предполагаю, что это должно иметь какое-то отношение к квалификаторам? Каким-то образом CDI «видит» эти два экземпляра, но решает, что ни один из них не подходит для моего запроса на инъекцию? это может быть?
Есть ли что-нибудь «очевидное», что приходит на ум, что я могу делать неправильно здесь? Я пытаюсь использовать CDI в первый раз, и возможно (или даже вероятно), что я где-то делаю что-то глупое :-)
Любая помощь или подсказка приветствуются и заранее большое спасибо!
Ниже я прикреплю «окружающие» классы для квалификатора, литерала аннотации и так далее для справки.
Интерфейс CustomerScoringInterface, реализуемый обоими модулями:
package de.otto.cccs.customerscoring.modules;
import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;
public interface CustomerScoringModule {
public ScoringModuleResponseVO process(ScoringRequestVO inputVO);
}
Одна из двух реализаций модуля (сейчас это всего лишь фиктивные реализации, и единственная разница заключается в выводе log.info() в методе process(), поэтому я включил здесь только одну из них):
package de.otto.cccs.customerscoring.modules;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import de.otto.cccs.customerscoring.modules.qualifiers.ScoringModule;
import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;
import lombok.extern.log4j.Log4j2;
@Log4j2
@Stateless
@LocalBean
@ScoringModule("AGE")
public class AgeModule implements CustomerScoringModule {
public AgeModule() {
super();
}
@Override
public ScoringModuleResponseVO process(ScoringRequestVO inputVO) {
log.info("processed AGE_MODULE");
return new ScoringModuleResponseVO();
}
}
Квалификатор @ScoringModule:
package de.otto.cccs.customerscoring.modules.qualifiers;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ScoringModule {
String value();
}
И AnnotationLiteral:
package de.otto.cccs.customerscoring.modules.qualifiers;
import javax.enterprise.util.AnnotationLiteral;
public class ScoringModuleLiteral extends AnnotationLiteral<ScoringModule> implements ScoringModule {
private static final long serialVersionUID = 1L;
private String value;
public ScoringModuleLiteral(String value) {
this.value = value;
}
@Override
public String value() {
return this.value;
}
}
И, наконец, мой пустой файл beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
@Inject @ScoringModule("AGE") CustomerScoringModule ageModule
работает? - person Nikos Paraskevopoulos   schedule 16.08.2017CustomerScoringModule
как локальный бизнес-интерфейс, поэтому он не включен в типы bean-компонентов CDI? Что произойдет, если вы опустите@LocalBean
(если это вообще возможно)? - person Nikos Paraskevopoulos   schedule 16.08.2017