编程语言
首页 > 编程语言> > Java CDI:基于限定符动态选择实现?

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