通过带有 table 个参数的注释选择 CDI bean
Selecting CDI bean by annotation with table of arguments
如何根据注解选择CDI java bean,然后注解提出table个参数?
使用示例展示问题比描述问题更容易。
假设对于每个问题类型的对象,我们必须选择合适的解决方案。
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) {
// ...
}
}
和第二个解决方案:
@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(Annotation...) 方法在内部如何工作,以及它如何比较注释,所以我不知道我的论点是什么应该放在那里以获得适当的解决方案。如果出现 A table ProblemType[] 类型的问题将包含一个参数,而 FirstSolution.class 被注释为 @SolutionQualifier 有两个参数,因此我不会得到正确的实例。
我没有找到使用 CDI 解决它的方法 API,而是:
我创建了另一个枚举:
public enum SoultionType {
A(ProblemType.A, ProblemType.C),
B(ProblemType.A);
//...
SoultionType(ProblemType problems...) {
// ...
}
public static SoultionType getByProblemType(ProblemType problem) {
// ...
}
}
改成SolutionQualifier里面只有SoultionType字段,所以比较没有问题。
如何根据注解选择CDI java bean,然后注解提出table个参数?
使用示例展示问题比描述问题更容易。
假设对于每个问题类型的对象,我们必须选择合适的解决方案。
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) {
// ...
}
}
和第二个解决方案:
@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(Annotation...) 方法在内部如何工作,以及它如何比较注释,所以我不知道我的论点是什么应该放在那里以获得适当的解决方案。如果出现 A table ProblemType[] 类型的问题将包含一个参数,而 FirstSolution.class 被注释为 @SolutionQualifier 有两个参数,因此我不会得到正确的实例。
我没有找到使用 CDI 解决它的方法 API,而是:
我创建了另一个枚举:
public enum SoultionType {
A(ProblemType.A, ProblemType.C),
B(ProblemType.A);
//...
SoultionType(ProblemType problems...) {
// ...
}
public static SoultionType getByProblemType(ProblemType problem) {
// ...
}
}
改成SolutionQualifier里面只有SoultionType字段,所以比较没有问题。