到目前为止,我成功使用了 google guice 2。在迁移到 guice 3.0 时,我遇到了辅助注入(inject)工厂的问题。假设以下代码
public interface Currency {}
public class SwissFrancs implements Currency {}
public interface Payment<T extends Currency> {}
public class RealPayment implements Payment<SwissFrancs> {
@Inject
RealPayment(@Assisted Date date) {}
}
public interface PaymentFactory {
Payment<Currency> create(Date date);
}
public SwissFrancPaymentModule extends AbstractModule {
protected void configure() {
install(new FactoryModuleBuilder()
.implement(Payment.class, RealPayment.class)
.build(PaymentFactory.class));
}
}
在创建注入(inject)器时,出现以下异常:
com.google.inject.CreationException: Guice creation errors:
1) Payment<Currency> is an interface, not a concrete class.
Unable to create AssistedInject factory. while locating Payment<Currency>
at PaymentFactory.create(PaymentFactory.java:1)
借助 guice 2 的辅助注入(inject)创建器,我的配置有效:
bind(PaymentFactory.class).toProvider(
FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));
到目前为止我发现的唯一解决方法是从工厂方法的返回类型中删除泛型参数:
public interface PaymentFactory {
Payment create(Date date);
}
有谁知道,为什么 guice 3 不喜欢工厂方法中的通用参数,或者我对辅助注入(inject)工厂的一般误解是什么?谢谢!
最佳答案
上面的代码有两个问题。
首先,RealPayment
工具 Payment<SwissFrancs>
,但是PaymentFactory.create
返回 Payment<Currency>
. Payment<SwissFrancs>
不能从返回 Payment<Currency>
的方法返回.如果更改 create
的返回类型至 Payment<? extends Currency>
, 然后 RealPayment
会起作用(因为它是一个 Payment
用于扩展 Currency
的东西)。
其次,您确实需要使用 implement
的版本这需要 TypeLiteral
作为它的第一个参数。这样做的方法是使用匿名内部类。您可以使用
new TypeLiteral<Payment<? extends Currency>>() {}
查看 Javadoc TypeLiteral
构造函数以获取更多信息。
关于java - guice 辅助注入(inject)工厂中通用返回类型的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5514115/