我正在使用guice 3和guice-servlet3。在模块中,我定义了这种绑定:
[...]
bind(View.class).annotatedWith(Names.named("view1")).to(View1Impl.class);
bind(View.class).annotatedWith(Names.named("view2")).to(View2Impl.class);
[...]
在注入的类View1Impl中,我定义了以下内容:
public class View1Impl {
@Inject @Named("view1") Provider<View> viewProvider;
@Inject
void init() {
View viewA = viewProvider.get();
View viewB = viewProvider.get();
log.debug(viewA == viewB);
log.debug(viewA == this);
}
}
两条语句均返回true。但是事实并非如此。
我究竟做错了什么?
最佳答案
如果您查看Guice的源代码,将可以清楚地知道实际完成了什么:
final ThreadLocal<Object[]> localContext;
/** Looks up thread local context. Creates (and removes) a new context if necessary. */
<T> T callInContext(ContextualCallable<T> callable) throws ErrorsException {
Object[] reference = localContext.get();
if (reference[0] == null) {
reference[0] = new InternalContext();
try {
return callable.call((InternalContext)reference[0]);
} finally {
// Only clear the context if this call created it.
reference[0] = null;
}
} else {
// Someone else will clean up this context.
return callable.call((InternalContext)reference[0]);
}
}
显然,注入对象时,Guice将其存储在该
ThreadLocal
变量中。现在,根据此代码片段,它将在注入时立即释放。因此,可能在您的“作用域”中将其初始化为其他位置,可能是在注射开始时-在注射结束时将其释放。关于java - guice-提供者总是返回相同的实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14748442/