Java CDI:基于限定符动态选择实现?
作者:互联网
我正在尝试通过使用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>.如果该方法只是创建并返回一个实现,则可以正常工作.我只是不知道如何检查实例E中的候选人.看起来“内容”的唯一方法似乎是Iterator< E>.但是,一旦我调用next(),它将尝试创建实现…但是不幸的是,为此调用了我的@Produces方法,从而创建了无限递归.我想念什么?如何检查候选人并选择一个?当然,我只想实例化其中之一.
在此先感谢您的帮助和提示!
解决方法:
我认为问题是您正在尝试选择注释的类,而不是将注释用作选择器限定符.使用该类直接搜索实现该类的实现.您需要使用@ImplDescriptor类创建AnnotationLiteral,以将其用作限定符来执行选择.像这样创建一个扩展AnnotationLiteral的类.
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方法.
instance.select(new ImplDescriptorLiteral("type1")).get();
有关更多信息,请参考Obtaining a contextual instance by programmatic lookup documentation.
标签:cdi,java 来源: https://codeday.me/bug/20191030/1967458.html