Java CDI:根据限定符动态选择实现? [英] Java CDI: Dynamically selecting an implementation based on qualifier?
问题描述
我正在尝试通过使用CDI使应用程序可扩展,但似乎我错过了一块拼图。
I'm trying to make an application extensible by using CDI, but it seems like I'm missing a piece of the puzzle.
我想要的:
具有全局配置,该配置将定义要使用的接口的实现。这些实现将有@ImplDescriptor(type =type1)等注释。
What I want: Have a global configuration that will define which implementation of an interface to use. The implementations would have annotations like @ImplDescriptor(type="type1").
我尝试过:
@Produces
public UEInterface createUserExit(@Any Instance<UEInterface> instance, InjectionPoint ip) {
Annotated annotated = ip.getAnnotated();
UESelect ueSelect = annotated.getAnnotation(UESelect.class);
if (ueSelect != null) {
System.out.println("type = " + ueSelect.type());
}
System.out.println("Inject is ambiguous? " + instance.isAmbiguous());
if (instance.isUnsatisfied()) {
System.out.println("Inject is unsatified!");
return null;
}
// this would be ok, but causes an exception
return instance.select(ueSelect).get();
// or rather this:
for (Iterator<UEInterface> it = instance.iterator(); it.hasNext();) {
// problem: calling next() will trigger instantiation which will call this method again :(
UEInterface candidate = it.next();
System.out.println(candidate.getClass().getName());
}
}
这段代码接近我见过的一个例子:@ Produces方法将用于选择和创建实例,候选列表被注入Instance< E>。如果方法只是创建并返回一个实现,它工作正常。我只是不知道如何检查和选择候选来自Instance< E>。查看内容的唯一方法似乎是Iterator< E>。但是一旦我调用next(),它就会尝试创建实现......不幸的是,调用我的@Produces方法,从而创建了一个无限的递归。我错过了什么?我怎么能够检查候选人并选择一个?当然我想只实例化其中一个......
This code is close to an example I've seen: The @Produces method will be used to select and create instances and a list of candidates is injected as Instance<E>. If the method simply creates and returns an implementation, it works fine. I just don't know how to examine and select a candidate from the Instance<E>. The only way of looking the the "contents" seems to be an Iterator<E>. But as soon as I call next(), it will try to create the implementation... and unfortunately, calls my @Produces method for that, thereby creating an infinite recursion. What am I missing? How can I inspect the candidates and select one? Of course I want to instantiate only one of them...
提前感谢任何帮助和提示!
Thanks in advance for any help and hints!
推荐答案
我认为问题是你试图选择注释的类而不是使用注释作为选择器限定符。使用该类直接搜索实现该类的实现。您需要使用@ImplDescriptor类创建AnnotationLiteral,以使用它作为限定符执行选择。像这样创建一个扩展AnnotationLiteral的类。
I think the issue is you are trying to select the annotation's class rather than using the annotation as a selector qualifier. Using the class directly searches for an implementation that implements that class. You need to create an AnnotationLiteral using the @ImplDescriptor class to perform a select using it as a qualifier. Create a class extending AnnotationLiteral like so.
public class ImplDescriptorLiteral extends AnnotationLiteral<ImplDescriptor> implements ImplDescriptor {
private String type;
public ImplDescriptorLiteral(String type) {
this.type = type;
}
@Override
public String type() {
return type;
}
}
然后你可以传递一个实例这个类使用你想要的类型的select方法。
then you can pass an instance of this class to the select method using the type you want.
instance.select(new ImplDescriptorLiteral("type1")).get();
请参阅通过程序化查找文档获取上下文实例以获取更多信息。
Refer to the Obtaining a contextual instance by programmatic lookup documentation for more information.
这篇关于Java CDI:根据限定符动态选择实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!