sol*_*l25 2 dependency-injection instance guice
我想为其中一个组件使用Guice的静态实例方法(非托管bean应该能够访问此类).我创建了这样的东西:
public class LookupService {
@Inject
private static Provider<Injector> injector = null;
private final ILookup<IWS> lookup;
@Inject
public LookupService(ILookup<IWS> lookup) {
this.lookup = lookup;
}
public static LookupService instance() {
return injector.get().getInstance(LookupService.class);
}
public <T extends IWS> T lookup(Class<T> localInterface) {
return lookup.lookup(localInterface);
}
Run Code Online (Sandbox Code Playgroud)
}
你怎么看待这个设计?关于这个的任何其他想法?(从非托管对象访问托管bean)
基本上,您正在寻找的模式称为"请求静态注入",并且有一个专门用于它的Binder方法.一旦你失败了,你的代码看起来很像Guice文档中的这个例子.
public class MainModule extends AbstractModule {
@Override public void configure() {
requestStaticInjection(LookupService.class);
}
}
public class LookupService {
/** This will be set as soon as the injector is created. */
@Inject
static Provider<LookupService> provider = null;
private final ILookup<IWS> lookup;
@Inject
public LookupService(ILookup<IWS> lookup) {
this.lookup = lookup;
}
public static LookupService instance() {
return provider.get();
}
public <T extends IWS> T lookup(Class<T> localInterface) {
return lookup.lookup(localInterface);
}
}
Run Code Online (Sandbox Code Playgroud)
几点说明:
虽然您仍然可以设置您的字段private,但请记住,这意味着如果没有Guice的私有字段访问魔法,您无法在测试中(或在将来的非Guice用法中)设置它.当使用注入字段时,我们经常将它们打包为私有,然后将测试放在同一个包中.
静态注入通常被视为只有在迁移到Guice时才能认可,或者当您使用其他无法更改的代码时.在可能的情况下,尽量避免全局状态 - 即使这意味着FooBean只生成数据并创建注入FooBeanService.
即使你可以在Injector任何你想要的地方注入,你可能会发现如果你只是注入一个更容易测试Provider<LookupService>.只有注入的Injector,如果你不知道你要什么类型的需要,直到运行时-例如,如果实现LookupService.lookup(...)使用Injector由类文字传递到喷油器获得一个实例.
事实上,从这里很难说,但ILookup似乎很像服务定位器模式,它解决了Guice通过依赖注入解决的确切类型的问题!如果是这种情况,你也可以重写ILookup来使用Guice:只需删除调用,LookupService.instance().lookup(Foo.class)然后创建一对匹配的@Inject static Provider<Foo> fooProvider和requestStaticInjection(FooUser.class).
希望有所帮助!