Guice 通用绑定接口到实现有界类型参数
Guice generic binding interface to implementation bounded type parameter
我正在开发一个基于 JAX-RS 的 Java 应用程序,使用 Google Guice 进行依赖注入。我的代码中有以下界面:
public interface LockProvider<L extends Lock> {
Optional<L> acquireLock(String lockId);
void releaseLock(L lock);
}
上述接口中,Lock是一个接口,定义如下:
public interface Lock {
String getLockId();
}
Lock接口实现如下class:
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接口实现如下class:
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
}
}
我不希望我的应用程序中的 classes 除了 LockProvider 之外了解 underLying 锁项,这就是我没有在 Lock 接口中包含 getUnderlyingLockItem 的原因。
现在,当我尝试将 LockProvider 绑定到 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 的子class。是否有可能完成我正在尝试做的事情,即将 LockProvider 绑定到 DynamoDBLockProvider(以干净高效的方式)?
您的 DynamoDBLockProvider
实例是 而不是 LockProvider<Lock>
实例。但它们 是 LockProvider<? extends Lock>
的 个实例。
一个平行的例子是 ArrayList<Integer>
的实例是 不是 List<Number>
的实例,但是 是 的实例List<? extends Number>
根据 this question.
将其应用于 Guice,您将得到完全相同的编译失败。假设您有这样的 class:
public class IntegerList extends ArrayList<Integer> {}
然后像这样绑定它是行不通的:
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)?
以下绑定将起作用:
binder.bind(new TypeLiteral<LockProvider<? extends Lock>>() {}).to(DynamoDBLockProvider.class);
我正在开发一个基于 JAX-RS 的 Java 应用程序,使用 Google Guice 进行依赖注入。我的代码中有以下界面:
public interface LockProvider<L extends Lock> {
Optional<L> acquireLock(String lockId);
void releaseLock(L lock);
}
上述接口中,Lock是一个接口,定义如下:
public interface Lock {
String getLockId();
}
Lock接口实现如下class:
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接口实现如下class:
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
}
}
我不希望我的应用程序中的 classes 除了 LockProvider 之外了解 underLying 锁项,这就是我没有在 Lock 接口中包含 getUnderlyingLockItem 的原因。
现在,当我尝试将 LockProvider 绑定到 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
您的 DynamoDBLockProvider
实例是 而不是 LockProvider<Lock>
实例。但它们 是 LockProvider<? extends Lock>
的 个实例。
一个平行的例子是 ArrayList<Integer>
的实例是 不是 List<Number>
的实例,但是 是 的实例List<? extends Number>
根据 this question.
将其应用于 Guice,您将得到完全相同的编译失败。假设您有这样的 class:
public class IntegerList extends ArrayList<Integer> {}
然后像这样绑定它是行不通的:
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)?
以下绑定将起作用:
binder.bind(new TypeLiteral<LockProvider<? extends Lock>>() {}).to(DynamoDBLockProvider.class);