Jersey/HK2 中一个接口的两个实现,首先在另一个中重用
Two implementations of one interface in Jersey/HK2, reuse first in other
我有一个简单实现的接口,比如说
interface MyService {
void doIt();
}
class MyServicePlain implements MyService{
@Inject
SomeOtherInterface
public void doIt () {
}
}
我想制作一个缓存 doIt
的缓存,所以我写了一个包装器 :
class CachingMyService implements MyService {
@Inject
MyService inner;
int cacheThingie;
public int doIt() {
if (cached) ... {
return cacheThingie;
}
else {
result = inner.doIt();
addToCache(result);
return result;
}
}
}
然后,我将这两个实现添加到我的活页夹中:
public class ApplicationBinder extends AbstractBinder {
protected void configure() {
this.bind(MyServicePlain.class).to(MyService.class).in(Singleton.class).ranked(2);
this.bind(CachingMyService.class).to(MyService.class).in(Singleton.class).ranked(2);
}
}
我收到错误抱怨:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no
object available for injection at
SystemInjecteeImpl(requiredType=MyService,parent=CachingMyService},position=-1,optional=false,self=false,unqualified=null,1102650897)
我尝试像这样使用 Qualitifaction:
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface NonCached {
}
@NonCached
class MyServicePlain implements MyService{
}
并使用它:
class CachingMyService implements MyService {
@Inject @NonCached
MyService inner;
但这也不管用。
像这样包装缓存服务的正确方法是什么?我怎样才能让hk2选择合适的实现?
当你想要限定不同的类型时,你需要使用qualifiedBy(Annotation)
方法。您还需要使用不同的限定符注释来注释每个注入点。
首先你需要注解并有办法获取它们的实例(qualifiedBy
方法需要注解实例)
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface NonCached {
class Literal extends AnnotationLiteral<NonCached> implements NonCached {
public static final NonCached INSTANCE = new Literal();
private Literal() {
}
}
}
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Cached {
class Literal extends AnnotationLiteral<Cached> implements Cached {
public static final Cached INSTANCE = new Literal();
private Literal() {
}
}
}
然后当你绑定它们时使用 qualifiedBy
this.bind(MyServicePlain.class).to(MyService.class)
.in(Singleton.class).qualifiedBy(NonCached.Literal.INSTANCE);
this.bind(CachingMyService.class).to(MyService.class)
.in(Singleton.class).qualifiedBy(Cached.Literal.INSTANCE);
然后在注入它们时,添加适用的限定符
@Inject
@NonCached
MyService service;
@Inject
@Cached
MyService service;
我有一个简单实现的接口,比如说
interface MyService {
void doIt();
}
class MyServicePlain implements MyService{
@Inject
SomeOtherInterface
public void doIt () {
}
}
我想制作一个缓存 doIt
的缓存,所以我写了一个包装器 :
class CachingMyService implements MyService {
@Inject
MyService inner;
int cacheThingie;
public int doIt() {
if (cached) ... {
return cacheThingie;
}
else {
result = inner.doIt();
addToCache(result);
return result;
}
}
}
然后,我将这两个实现添加到我的活页夹中:
public class ApplicationBinder extends AbstractBinder {
protected void configure() {
this.bind(MyServicePlain.class).to(MyService.class).in(Singleton.class).ranked(2);
this.bind(CachingMyService.class).to(MyService.class).in(Singleton.class).ranked(2);
}
}
我收到错误抱怨:
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=MyService,parent=CachingMyService},position=-1,optional=false,self=false,unqualified=null,1102650897)
我尝试像这样使用 Qualitifaction:
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface NonCached {
}
@NonCached
class MyServicePlain implements MyService{
}
并使用它:
class CachingMyService implements MyService {
@Inject @NonCached
MyService inner;
但这也不管用。
像这样包装缓存服务的正确方法是什么?我怎样才能让hk2选择合适的实现?
当你想要限定不同的类型时,你需要使用qualifiedBy(Annotation)
方法。您还需要使用不同的限定符注释来注释每个注入点。
首先你需要注解并有办法获取它们的实例(qualifiedBy
方法需要注解实例)
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface NonCached {
class Literal extends AnnotationLiteral<NonCached> implements NonCached {
public static final NonCached INSTANCE = new Literal();
private Literal() {
}
}
}
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Cached {
class Literal extends AnnotationLiteral<Cached> implements Cached {
public static final Cached INSTANCE = new Literal();
private Literal() {
}
}
}
然后当你绑定它们时使用 qualifiedBy
this.bind(MyServicePlain.class).to(MyService.class)
.in(Singleton.class).qualifiedBy(NonCached.Literal.INSTANCE);
this.bind(CachingMyService.class).to(MyService.class)
.in(Singleton.class).qualifiedBy(Cached.Literal.INSTANCE);
然后在注入它们时,添加适用的限定符
@Inject
@NonCached
MyService service;
@Inject
@Cached
MyService service;