我试图通过使用 CDI 使应用程序可扩展,但似乎我错过了一块拼图。
我想要什么:有一个全局配置,它将定义要使用的接口的实现。实现将具有 @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 方法,从而创建了无限递归。我错过了什么?我如何检查候选人并选择一个?当然,我只想实例化其中一个...
提前感谢您的任何帮助和提示!