guice 辅助注入工厂中通用返回类型的问题

2022-09-04 21:45:59

到目前为止,我成功地使用了谷歌指南2。在迁移到 guice 3.0 时,我在辅助注射工厂方面遇到了麻烦。假设以下代码

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));
    }
}

在创建注入器时,我得到以下异常:

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 的辅助注入创建者,我的配置可以正常工作:

bind(PaymentFactory.class).toProvider(
FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));

到目前为止,我发现的唯一解决方法是从工厂方法的返回类型中删除泛型参数:

public interface PaymentFactory {
    Payment create(Date date);
}

有谁知道,为什么guice 3不喜欢工厂方法中的通用参数,或者我通常误解了辅助注射工厂?谢谢!


答案 1

上面的代码有两个问题。

首先,实现 ,但返回 。不能从返回 的方法返回 。如果将 返回类型更改为 ,则将起作用(因为它是扩展的内容)。RealPaymentPayment<SwissFrancs>PaymentFactory.createPayment<Currency>Payment<SwissFrancs>Payment<Currency>createPayment<? extends Currency>RealPaymentPaymentCurrency

其次,您确实需要使用该版本,该版本将 a 作为其第一个参数。执行此操作的方法是使用匿名内部类。要表示“付款”,您可以使用implementTypeLiteral

new TypeLiteral<Payment<? extends Currency>>() {}

有关更多信息,请参阅该构造函数的 Javadoc。TypeLiteral


答案 2

推荐