Выбор компонента CDI по аннотации с таблицей аргументов - PullRequest
0 голосов
/ 25 июня 2018

Как выбрать Java-бин CDI на основе аннотации, тогда аннотация представляет таблицу аргументов?

Проблему легче показать на примере, чем описать.

Предположим, что для каждого объекта типа Задача мы должны выбрать правильное решение.

public class Problem {

    private Object data;
    private ProblemType type;

    public Object getData() { return data; }
    public void setData(Object data) { this.data = data; }
    public ProblemType getType() { return type; }
    public void setType(ProblemType type) { this.type = type;}
}

Существует несколько типов проблем:

public enum ProblemType {
    A, B, C;
}

Существует несколько решений:

public interface Solution {
    public void resolve(Problem problem);
}

подобно FirstSolution :

@RequestScoped
@SolutionQualifier(problemTypes = { ProblemType.A, ProblemType.C })
public class FirstSolution implements Solution {

    @Override
    public void resolve(Problem problem) {
        // ...
    }
}

и SecondSolution :

@RequestScoped
@SolutionQualifier(problemTypes = { ProblemType.B })
public class SecondSolution implements Solution {

    @Override
    public void resolve(Problem problem) {
        // ...
    }
}

Решение следует выбирать на основе аннотации @ SolutionQualifier :

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SolutionQualifier {

    ProblemType[] problemTypes();

    public static class SolutionQualifierLiteral extends AnnotationLiteral<SolutionQualifier> implements SolutionQualifier {

        private ProblemType[] problemTypes;

        public SolutionQualifierLiteral(ProblemType[] problems) {
            this.problemTypes = problems;
        }

        @Override
        public ProblemType[] problemTypes() {
            return problemTypes;
        }
    }
}

По SolutionProvider :

@RequestScoped
public class DefaultSolutionProvider implements SolutionProvider {

    @Inject
    @Any
    private Instance<Solution> solutions;

    @Override
    public Instance<Solution> getSolution(Problem problem) {

        /**
         * Here is the problem of choosing proper solution.
         * I do not know how method {@link javax.enterprise.inject.Instance#select(Annotation...)}
         * works, and how it compares annotations, so I do no know what argument I should put there
         * to obtain proper solution.
         */

        ProblemType[] problemTypes = { problem.getType() };
        return solutions.select(new SolutionQualifier.SolutionQualifierLiteral(problemTypes));
    }
}

И в последнем есть проблема: я не знаю, как метод javax.enterprise.inject.Instance # select (Аннотация ...) работает внутренне, и как он сравнивает аннотации, поэтому я не знаю, какой аргумент я должен привести там, чтобы получить правильное решение.Если возникает проблема типа A table ProblemType [] будет состоять из одного аргумента, тогда как FirstSolution.class аннотируется с помощью @ SolutionQualifier имея два аргумента, поэтому я не получу правильный экземпляр.

1 Ответ

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

Я не нашел способа решить его с помощью CDI API, вместо этого:

Я создал другое перечисление:

public enum SoultionType {
    A(ProblemType.A, ProblemType.C), 
    B(ProblemType.A);

    //...

    SoultionType(ProblemType problems...) {
        // ...
    }

    public static SoultionType getByProblemType(ProblemType problem) {
        // ...
    }
}

Изменено, поэтому SolutionQualifier содержит только поле SoultionType, поэтому при сравнении проблем не возникает.

...