我有一個相互自動裝配的Spring bean的圖形。重簡化圖解:Spring創建單例的多個實例?
<context:annotation-config/>
<bean class="Foo"/>
<bean class="Bar"/>
<bean class="Baz"/>
...
public class Foo {
@Autowired Bar bar;
@Autowired Baz baz;
}
public class Bar {
@Autowired Foo foo;
}
public class Baz {
@Autowired Foo foo;
}
所有這些豆子不具備規定範圍這意味着他們是單身(使他們明確單身人士不會改變任何東西,我試過)。
的問題是,一單個應用上下文的實例化後,的Bar
和Baz
實例包含的Foo
不同實例。這怎麼會發生?
我試圖創建Foo
的公共無參數構造函數,調試已確認Foo
被多次創建。所有這些作品的堆棧跟蹤爲here。
我也曾嘗試啓用調試日誌記錄春天,和所有其他線路中,得到如下:
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
我明白我的豆交叉引用對方,但我希望Spring框架尊重單例作用域並初始化單例bean一次,然後將其自動裝入任何想要它的人。
一個有趣的事實是,如果我使用舊學校private
構造函數與public static Foo getInstance
訪問器,這工作得很好 - 在上下文設置過程中不會引發異常。
FWIW,我正在使用Spring 3.0.5版本(也嘗試使用3.1.2,結果相同)和o.s.c.s.ClassPathXmlApplicationContext(String ...configLocations)
的構造函數。
我可以很容易地將我的代碼轉換爲使用靜態初始化,但我想明白爲什麼春天會這樣。這是一個錯誤?
編輯:一些額外的調查顯示,應用程序上下文初始化
- 後,以
context.getBean(Foo.class)
所有後續請求始終返回Foo
相同的實例。 - 用setter替代
@Autowired
(約20個這個bean的用法)仍然導致這個對象的多重構造,但是所有的依賴關係都被注入了和相同的引用。
對我而言以上表明這是一個與@Autowired
實現有關的Spring bug。如果我設法獲取任何有用的信息,我將發佈到Spring社區論壇併發布回來。
這可能很明顯,但只有1個JVM在使用嗎?循環依賴關係? – 2012-07-18 17:49:28
是的,這只是一個JVM。循環依賴 - 是的,但我相信我在我的帖子中解釋了這一點。 – mindas 2012-07-18 17:50:01
我明白了,但如果你有例如構造函數注入會發生什麼? Spring如何解決這個問題? – 2012-07-18 17:51:13