将通用抽象超级 class 绑定到多个非通用实现 classes
Binding a generic abstract super class to multiple non-generic implementation classes
我相信我的设置有点不合常规,所以解释会更长一些。
我有一个抽象的超级class,方法是
public abstract T execute(P parameters);
我有一组实现 classes 扩展它,并在扩展语句中分配各个类型。这意味着实现不是通用的。
我通过注解@Example 获取了所有的实现。我使用 ClassGraph 提取有关这些 classes 的信息。通过它,我不仅获得了实现,还获得了具有定义类型的正确 superclass。
但是我现在无法使用 Guice bind().to();
提供更多背景知识...
我有一组实现 classes,它与外部 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 绑定不考虑这些,因此未找到绑定。
接下来我阅读了 Guice 中的泛型绑定和 TypeLiteral。但是我没有找到让编译器满意的方法。
我从 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;
如我所料,结果正确。
我相信我的设置有点不合常规,所以解释会更长一些。 我有一个抽象的超级class,方法是
public abstract T execute(P parameters);
我有一组实现 classes 扩展它,并在扩展语句中分配各个类型。这意味着实现不是通用的。
我通过注解@Example 获取了所有的实现。我使用 ClassGraph 提取有关这些 classes 的信息。通过它,我不仅获得了实现,还获得了具有定义类型的正确 superclass。
但是我现在无法使用 Guice bind().to();
提供更多背景知识...
我有一组实现 classes,它与外部 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 绑定不考虑这些,因此未找到绑定。
接下来我阅读了 Guice 中的泛型绑定和 TypeLiteral。但是我没有找到让编译器满意的方法。
我从 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;
如我所料,结果正确。