繁体   English   中英

将泛型抽象超 class 绑定到多个非泛型实现类

[英]Binding a generic abstract super class to multiple non-generic implementation classes

我相信我的设置有点不合常规,所以解释会更长一些。 我有一个抽象的超class,用方法

public abstract T execute(P parameters);

我有一组扩展它的实现类,并在扩展语句中分配单独的类型。 这意味着实现不是通用的。

我通过注释@Example 获取所有实现。 我使用 ClassGraph 来提取有关这些类的信息。 通过它,我不仅获得了实现,还获得了具有已定义类型的正确超类。

但是我现在无法使用 Guice bind().to();

为了提供更多背景...

我有一组实现类,它们与外部 API 通信。 每个 class 都与一个单独的区域通信。 我希望我自己的服务 API 不依赖于特定的实现。 我看不到未来,很有可能我们需要在以后更灵活地绑定实现(例如,同一个调用有 3 个不同的实现)。 外部服务是高度灵活的,因此消费者必须具有类似的灵活性。

出于这个原因,我的目标是使用 guice 注释绑定

bind(super.class).annotatedWith(Names.named(path)).to(implementation.class);

另一方面,在我自己的服务 API 中,我想使用 @Named 注释的用户方法注入来定义绑定接收。

@Inject
  public void setImplementation(@Named(path) Super<InputType, OutputType> implementation){...}

上述方法的问题是通用的。 super.class 绑定不考虑这些,因此没有找到绑定。

接下来我使用 TypeLiteral 阅读了 Guice 中的泛型绑定。 但是我没有找到让编译器满意的方法。

从 ClassGraph 我收到 ClassInfo。 所以我尝试了以下设置

//class list is the result of ClassGraph
for (Class<?> entry : classList){
  Class<? extends Super> implementationClass = (Class<? extends Super> entry;
  String value = entry.getAnnotation(Example.class).value();
  TypeLiteral<? extends Super> typeLiteral = TypeLiteral.get(implementationClass);
  TypeLiteral<?> supertype = typeLiteral.getSupertype(Super.class);

  //now the trials start and all are wrong, annotation is left out for now
  bind(impelmentationClass.getSuperclass()).to(implementationClass);
  bind(impelmentationClass.getSuperclass()).to(entry);
  bind(impelmentationClass.getSuperclass()).to(typeLiteral);
  bind(supertype).to(implementationClass);
  bind(supertype).to(entry);
  bind(supertype).to(typeLiteral);
}

我正在尝试的是不可能的,还是我使用 TypeLiteral 错误? 我确实搜索了两天并尝试了更多不同的方法(这只是离家最近的)。 所以我有点陷入僵局,我希望其他人之前遇到过这个问题:)

任何帮助表示赞赏

我只是试了一下(可能不完全相同),但这似乎在我的环境中有效:

public abstract class ChequePrinter<T> implements Printer<T, PrintLayout> {
    public abstract print(T cheque);
}

public VoidChequePrinter extends ChequePrinter<VoidCheque> {
    public print (VoidCheque cheque);
}

非常简单,除了我打印到 PrintLayout 而不是网络请求,但这无关紧要。 现在对于我的示例,我只是硬编码了 class 定义,而不是从 ClassGraph 中提取它们,但只要:

Class<?> entry is a regular class

应该没问题。 这是我刚刚使用的:

// should be the same as entry
Class<? extends ChequePrinter<?>> clazz = VoidChequePrinter.class;  
TypeLiteral typeLiteral = TypeLiteral.get(clazz.getGenericSuperClass());
bind(typeLiteral).annotatedWith(Names.named("Void")).to(clazz);

在我的测试 class VoidChequePrinterTest我有:

@Inject @Named("Void") ChequePrinter<VoidCheque> printer;

正如我所期望的那样,它可以得到正确的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM