我有一个相互自动装配的 Spring bean 图。高度简化的插图:
<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;
}
所有这些 bean 都没有指定范围,这意味着它们是单例(使它们显式单例不会改变任何东西,我已经尝试过)。
问题在于,在单个应用程序上下文实例化之后,实例Bar
和Baz
包含. 这怎么可能发生?Foo
我试图创建 public no args 构造函数,Foo
并且调试已确认Foo
多次创建。所有这些创作的堆栈跟踪都在这里。
我还尝试为 Spring 启用调试日志记录,在所有其他行中,得到以下内容:
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'
我知道我的 bean 是相互交叉引用的,但我希望 Spring 框架尊重单例范围并初始化一个单例 bean,然后将它自动连接到任何想要它的人。
有趣的事实是,如果我使用带有访问器的老式private
构造函数public static Foo getInstance
,这工作得很好——在上下文设置期间不会抛出异常。
FWIW,我正在使用带有o.s.c.s.ClassPathXmlApplicationContext(String ...configLocations)
构造函数的 Spring 版本 3.0.5(也尝试使用 3.1.2,结果相同)。
我可以轻松地将我的代码转换为使用静态初始化程序,但我想了解为什么 Spring 会以这种方式运行。这是一个错误吗?
编辑:一些额外的调查表明
- 初始化应用程序上下文后,所有后续请求
context.getBean(Foo.class)
始终返回相同的Foo
. @Autowired
用 setter替换(这个 bean 大约 20 次使用)仍然会导致这个对象的多个构造,但是所有依赖项都注入了相同的引用。
对我来说,上面表明这是一个与@Autowired
实现有关的 Spring 错误。如果我设法获得任何有用的信息,我将发布到 Spring 社区论坛并返回这里。