2013-10-07 36 views

回答

4

不是一般做是因爲一個靜態變量不能有一個範圍,即它只是一個全班(閱讀應用程序),因此它沒有任何意義,因爲每個實例都將嘗試將其設置爲基於一個新的價值在當前範圍內。

+0

我以爲我自己,感謝claryfing那。 – VWeber

8

這是不可能當前,但它在理論上是不可能的。

對方回答表明,這是不可能的,但解釋說明注射的方式縫2的工作,我會嘗試從內存形容它。一些僞代碼:

@Name("a") 
class A() { 
    @In 
    B b; 

    void something() { 
     b.doTheThing(); 
    } 
} 

Seam 2支持通過BijectionInterceptor注入。爲了讓攔截器工作,Seam創建了組件的代理實例。在這裏,當a.something方法被調用時,它會被截取,並且proxified b實例確實會就在a的實例字段b注入。如果B駐留的上下文在該時刻未處於活動狀態,則注入將失敗,並且a.something方法調用也會失敗。

現在讓我們看看類似的例子爲CDI:

class A() { 
    @Inject 
    B b; 

    void something() { 
     b.doTheThing(); 
    } 
} 

在CDI仍有代理。但注射的方式不同。 CDI引入了上下文引用的概念。這是存儲在a.b字段中的內容。當a.something被稱爲沒有什麼有趣的事情發生。在任何情況下都不可能有B實例,並且a.something方法仍然會被調用。但是當涉及到調用b.doTheThing方法時 - 那是CDI開始尋找實際B實例的時候。例如,有可能獲得ContextNotActiveException

因此,這似乎是可能的。我發現some interesting notes在老焊接部位,這可能,爲什麼這還沒有實現解釋:

靜態注射

注射靜態成員有幾個問題:

  • 一個類可以多個應用程序之間共享,以及Java EE規範沒有定義該規則。
  • 在Java EE外部,很難準確定義何時注入靜態成員。

不過,也有這幾大usecases的:

  • 記錄器注入,
  • 注射實體類和
  • 注入與鈍化範圍的對象。

所以我們確實需要在這裏支持一些東西。也許這將是不夠的說:bean的第一個實例進行實例化之前

  • 無靜電注射共享庫,並
  • 靜態字段注入(但隨後靜態注入將不支持對非 - 大豆類)。

有專用於靜態注射開放CDI問題:CDI-51

+2

這是一個非常好的答案。只是想踢你另一個原因,你可能想這樣做。如果您正在遷移遺留應用程序,則可以使用靜態注入來幫助緩解從靜態過渡到DI的痛苦。 –

+0

斯圖爾特道格拉斯關於CDI注射方法的文章:https://developer.jboss.org/blogs/stuartdouglas/2010/10/12/weld-cdi-and-proxies –

0

很明顯,你不應該這樣做,但有時候我想你必須做,因爲有時候有些對象實例化了一些對象(例如使用ServiceLoader),並且你想注入它們。這裏有一個你可以做的破解:

class StaticallyInjected { 
    private static MyBean bean; 

    void inject (@Observes @Initialized (ApplicationScoped.class) Object x, 
       MyBean bean) { 
    StaticallyInjected.bean = bean; 
    } 
} 
+0

什麼是'對象x'在這裏做什麼? –

+0

我從來不屑於查看實際類型。這個想法是搭載到應用程序範圍初始化上,這是註釋的作用。我猜這是代表你的應用程序的某種對象,可能取決於CDI的實現 –

相關問題