我有一个相互自动装配的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