【问题标题】:Selecting CDI bean by annotation with table of arguments通过带有参数表的注释选择 CDI bean
【发布时间】:2018-06-25 16:00:06
【问题描述】:

如何根据注解选择CDI java bean,然后注解构成参数表?

用一个例子来展示这个问题比描述更容易。

假设对于每个问题类型的对象,我们必须选择合适的解决方案。

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;
        }
    }
}

解决方案提供者

@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(Annotation...) 如何在内部工作,以及它如何比较注释,所以我不知道我应该在那里获得什么参数适当的解决方案。如果出现 A 类型的问题,表 ProblemType[] 将由一个参数组成,而 FirstSolution.class@ 注释SolutionQualifier 有两个参数,因此我不会得到正确的实例。

【问题讨论】:

  • CDI 规范 v2.0 指定重复限定符,请参阅第 2.3.6 节。如果您在 CDI 2 中,它可能适合您。
  • AnnotationLiteral 匹配字段值和 annotationType。在这种情况下,problemTypes 中的相等。通常,CDI 不鼓励将Arrays 用于限定符字段,除非它们被标记为@NonBinding。无论如何,要解决问题,您可以覆盖AnnotationLiteralequals() 而不是equality 检查,而是执行自己的containedIn 检查。

标签: java jakarta-ee cdi


【解决方案1】:

我没有找到使用 CDI API 解决它的方法,而是:

我创建了另一个枚举:

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

    //...

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

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

改变了SolutionQualifier里面只有SoultionType字段,所以比较没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多