2013-10-11 6 views
3

應用程序上下文的典型部分:彈簧IOC:取決於上覆蓋懶惰-INIT

<bean id="option_A" class="class_a" lazy-init="true"/> 
<bean id="option_B" class="class_b" lazy-init="true" depends-on="setup_bean"/> 
<alias name="option_${OPTION_PROPERTY}" alias="thingChosen"/> 
<bean id="setup_bean" class="class_setup" lazy-init="true"/> 

這裏的概念是,如果OPTION_PROPERTY被設置爲 「A」,然後

<bean id="foo" class="whatever"><property name="bar" ref="thingChosen"/></bean> 

將得到一個注入bar屬性的class_a實例,如果該屬性設置爲「B」,那麼它將獲得一個注入類b的實例,但是類b對setup_bean具有隱藏的依賴關係(哪個類缺少),所以必須先創建setup_bean。

發生什麼事是,如果OPTION_PROPERTY設置爲「A」,那麼setup_bean仍然被創建。我試過使用Spring 3.2.4.RELEASE,它是一致的。這似乎是我的錯誤或誤解。

如果一個bean是lazy-init,那麼不應該依賴於bean等待,直到這個bean在自己創建之前被懶惰地創建?

回答

2

如果一個bean是lazy-init,那麼不應該依賴於bean等到 這個bean在自己創建之前是懶洋洋地創建的嗎?

是的。換句話說,option_B將不會被創建,直到setup_bean被請求和初始化。如果首先請求option_B,那麼將強制setup_bean首先被初始化。

The documentation says

然而,當一個延遲初始化bean是一個單 豆的依賴不是延遲初始化,在ApplicationContext在啓動時創建的 延遲初始化豆,因爲它必須滿足單身的依賴關係。

因此,該bean聲明

<bean id="foo" class="whatever"><property name="bar" ref="thingChosen"/></bean> 

將強制的thingChosen初始化,在這種情況下,混疊option_A

我無法重現您所遇到的(而且不應該)。仔細檢查你在做什麼。也許另一個bean引用setup_bean

下面是一個SSCCE

public class Test { 
    public static void main(String[] args) throws Exception { 
     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 
     System.out.println("context initialized"); 
     context.getBean("shouldnot"); 
    } 
    public static class MyClass { 
     public MyClass() { 
      System.out.println("myclass"); 
     } 
    } 
    public static class SetupBean { 
     public SetupBean() { 
      System.out.println("setup"); 
     } 
    } 
    public static class MyOtherClass { 
     private MyClass myClass; 
     public MyOtherClass() { 
      System.out.println("myotherclass"); 
     } 
     public MyClass getMyClass() { 
      return myClass; 
     } 
     public void setMyClass(MyClass myClass) { 
      this.myClass = myClass; 
     } 
    } 
} 

spring.xml

<bean id="myref" class="test.Test$MyClass" lazy-init="true"></bean> 
<bean id="shouldnot" class="test.Test$MyClass" lazy-init="true" depends-on="setup_bean"></bean> 

<bean class="test.Test$MyOtherClass" > 
    <property name="myClass" ref="myref"></property> 
</bean> 

<bean id="setup_bean" class="test.Test$SetupBean" lazy-init="true"></bean> 

它打印(減去春節日誌)

myotherclass 
myclass 
context initialized 
setup 
myclass 

換句話說,setup只有當請求shouldnot創建。

+0

這是一個相當全面的證明。我會回去在我的代碼,看看我是否能辨別任何其他可以想到的原因我的「setup_bean」可稱爲發揮作用。我根本不認爲是有什麼關係呢?我正在使用這個技巧來有效地執行上下文中的if/else邏輯。通過文檔 – nsayer

+0

@nsayer掃描我沒有看到任何指向這樣一個關於混淆的結論。無論如何,它解決了'option_A'。 –

+0

@nsayer我不知道你的'如果-else'適用什麼,但你可能會更好過使用'Profiles'。 –

0

事實證明,在context的其他地方,還有這個小寶石:

<context:annotation-config /> 

此,它的出現,在延遲實例結果被忽略。

試圖找出排除機器的工作原理是下一個步驟,但外的範圍爲這個問題。

+0

單靠這一點,這還不夠。你必須有一些強制bean被注入的註解。 –