簡體   English   中英

guice-提供者總是返回相同的實例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM