java - Guice 通用绑定(bind)接口(interface)到实现有界类型参数

标签 java generics guice

我正在开发一个基于 JAX-RS 的 Java 应用程序,使用 Google Guice 进行依赖注入(inject)。我的代码中有以下接口(interface):

public interface LockProvider<L extends Lock> {
    Optional<L> acquireLock(String lockId);

    void releaseLock(L lock);
}

上面的接口(interface)中,Lock是一个接口(interface),定义如下:

public interface Lock {
    String getLockId();
}

Lock接口(interface)由以下类实现:

public class DynamoDBLock implements Lock {
    private final String lockId;
    private final LockItem underLyingLock;

    public DynamoDBLock(final String lockId, final LockItem underLyingLock) {
    this.lockId = lockId;
    this.underLyingLock = underLyingLock;
    }

    @Override
    public String getLockId() {
        return lockId;
    }

    public LockItem getUnderlyingLock() {
        return underlyingLock;
    }
}

LockProvider接口(interface)由以下类实现:

public class DynamoDBLockProvider implements LockProvider<DynamoDBLock> {
    Optional<DynamoDBLock> acquireLock(String lockId) {
        //implementation here
    }

    void releaseLock(DynamoDBLock lock) {
        LockItem underlyingLockItem = lock.getUnderlyingLockItem();
        //do something with underlyingLockItem
    }
}

我不希望应用程序中除 LockProvider 之外的类了解 underLying 锁项,这就是为什么我没有在 Lock 接口(interface)中包含 getUnderlyingLockItem。

现在,当我尝试将 LockProvider 绑定(bind)到 DynamoDBLockProvider 时,如下所示:

bind(new TypeLiteral<LockProvider<Lock>>() {}).to(DynamoDBLockProvider.class);

我在 Eclipse 中收到以下编译错误:

The method to(Class<? extends LockProvider<Lock>>) in the type LinkedBindingBuilder<LockProvider<Lock>> is not applicable for the arguments (Class<DynamoDBLockProvider>)

我了解 DynamoDBLockProvider 不是 LockProvider 的子类。是否可以完成我想要做的事情,即将 LockProvider 绑定(bind)到 DynamoDBLockProvider (以干净高效的方式)?

最佳答案

您的 DynamoDBLockProvider 实例不是 LockProvider<Lock> 的实例。但它们 LockProvider<? extends Lock> 的实例。

一个并行的例子是 ArrayList<Integer> 的实例不是 List<Number> 的实例但 List<? extends Number> 的实例根据this question .

将其应用于 Guice,您将得到完全相同的编译失败结果。假设你有一个这样的类:

public class IntegerList extends ArrayList<Integer> {}

然后像这样绑定(bind)它是行不通的:

binder.bind(new TypeLiteral<List<Number>>() {}).to(IntegerList.class); //won't compile

Is it possible to accomplish what I am trying to do, i.e. bind LockProvider to DynamoDBLockProvider (in a clean and efficient way)?

以下绑定(bind)将起作用:

binder.bind(new TypeLiteral<LockProvider<? extends Lock>>() {}).to(DynamoDBLockProvider.class);

关于java - Guice 通用绑定(bind)接口(interface)到实现有界类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41528943/

相关文章:

java - 使用 aws-secretsmanager-jdbc 和 Node.js 连接到 RDS?

java - 将大型字符串数组作为 VarChar2 传递到 SQL 中

java - junit 断言语句

hibernate - 使用持久引用保留对象时,使用JPA遇到数据库死锁

scala - scala案例类中的Google Guice字段注入(inject)

java - 从集合中返回唯一元素的正确方法

generics - 如何确保泛型中的类型实现 Dart 中的某些运算符?

Java 泛型 - 有界类型参数

java - 无界通配符类型 List<?> 和原始类型 List 有什么区别?

Java:使用 Inject 注释对类进行 Junit