[英]guice - Provider returns always same instance
我正在使用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。 但是事實並非如此。
我究竟做錯了什么?
您可能已經檢查了這一點-列出了您使用的“那種”綁定-但是值得仔細檢查一下,在未編輯的代碼中,所有涉及的類都不會用@Singleton
謹慎地注釋或綁定到Singleton.class
范圍。 此外,請確保沒有任何綁定使用toInstance()
,它當然總是在所有情況下都返回該預先構造的實例,並且實際上是單例綁定。
我們遇到了一個案例,我們重構了bindView
方法,最終忘記了將其設置為始終將其參數綁定為單例(這樣,視圖的父容器和視圖的控制器可以注入同一視圖)。
除非Danyel暗示過,否則Guice中編碼了循環依賴項檢測 ,並且由於您正在@Inject
注釋方法中調用provider.get()
,因此您可能正在調用它。
如果您查看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
變量中。 現在,根據此代碼片段,它將在注入時立即釋放。 因此,可能在您的“作用域”中將其初始化為其他位置,可能是在注入開始時-在注入結束時被釋放了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.