min*_*das 16 java singleton spring autowired applicationcontext
我有一个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;
}
Run Code Online (Sandbox Code Playgroud)
所有这些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'
Run Code Online (Sandbox Code Playgroud)
我知道我的bean是相互交叉引用的,但我希望Spring框架能够尊重单例范围并初始化一个单例bean,然后将它自动装配给任何想要它的人.
有趣的事实是,如果我使用private带有public static Foo getInstance访问器的旧学校构造函数,这很好用 - 在上下文设置期间不会抛出异常.
FWIW,我正在使用Spring版本3.0.5(也尝试使用3.1.2,结果相同)和o.s.c.s.ClassPathXmlApplicationContext(String ...configLocations)构造函数.
我可以轻松地将我的代码转换为使用静态初始化程序,但我想理解为什么Spring会以这种方式运行.这是一个错误吗?
编辑:一些额外的调查显示
context.getBean(Foo.class) 始终返回相同的实例Foo.@Autowired用setter 替换(这个bean的大约20个用法)仍会导致该对象的多个构造,但是所有依赖项都使用相同的引用注入.对我来说,这表明这是一个与@Autowired实现有关的Spring bug .如果我设法获得任何有用的东西,我将发布到Spring社区论坛并在此发回.
roo*_*kit 13
如果您不小心上下文,子上下文可以重新实例化相同的单例bean:组件扫描注释(还有其他Spring上下文扫描注释,例如MVC和其他注释).在Web应用程序中使用Spring servlet时,这是一个常见问题,请参阅为什么DispatcherServlet创建另一个应用程序上下文?
确保您没有在子上下文中重新扫描组件,或者您只扫描特定的包/注释,并从根上下文组件扫描中排除所述包/注释.