Внедрение экземпляра Java CDI по универсальному типу - PullRequest
0 голосов
/ 23 мая 2018

Я хочу написать универсальные объекты валидатора, которые могут быть внедрены во время выполнения, выбирая конкретный bean-компонент для проверки, но я не могу заставить работать инъекцию.Вот классы интерфейсов:

public interface GenericValidator<T> {

    String getConfigurationCode();

    ErrorMessages validate(T toValidate);
}

public class GenericValidatorConstructor<T>  {

    @Inject
    private Instance<GenericValidator<T>> delegators;

    public List<GenericValidator<T>> getValidatorsByConfig(String configCode) {
        List<GenericValidator<T>> result = new ArrayList<GenericValidator<T>>();
        for (GenericValidator<T> validator : delegators) {
            if (configCode != null && configCode.equals(validator.getConfigurationCode()) ) {
                result.add(validator);
            }
        }
        return result;
    }
}

затем я реализовал конкретный класс со ссылкой на строку, например, так:

@Override
public String getConfigurationCode() {
    return "GENERIC_PASSWORD";
}

@Override
public ErrorMessages validate(String toValidate) {
    return null;
}

В ejb без состояния, который я внедрил таким образом

@Inject
private GenericValidatorConstructor<String> passwordValidatorConstructor;

, а затем вызвал метод

passwordValidatorConstructor.getValidatorsByConfig("GENERIC_PASSWORD");

, но внутри делегаторов getValidatorsByConfig Instance<GenericValidator<T>> - пустая коллекция, и я не знаю почему.Чего мне не хватает?

1 Ответ

0 голосов
/ 23 мая 2018

Замените

@Inject  
private Instance<GenericValidator<T>> delegators;

на:

@Any 
@Inject 
private Instance<GenericValidator<?>> delegators;

Тогда внедрение Instance сможет внедрить все реализации вашего GenericValidator, а затем вы можете использовать GenericValidator.getConfigurationCode длявыберите соответствующий тип или используйте Instance.select(TypeLiteral<MyConcreteType>{}), чтобы выбрать соответствующий тип бетона

...