Spring creating multiple instances of a singleton?

心已入冬 提交于 2019-11-30 17:24:17
rootkit

Child context(s) can reinstantiate the same singleton beans if you are not careful with context:component-scan annotations (there are other Spring context scan annotations as well such as MVC ones and others). This is a common problem when using Spring servlets in web applications, see Why DispatcherServlet creates another application context?

Make sure you are not re-scanning your components in child contexts, or you are scanning only specific packages/annotations and excluding said packages/annotations from root context component scan.

For some reason we are getting this popping up randomly in integration tests and services as well (spring version 4.1.4, java 1.8).

Looks like there might be more than one culprit - Autowiring appeared to be causing this at first.

However, we have resolved the most consistent failures by ensuring we give each impacted bean an 'id' field.

Try using setter injection instead of constructor way and see if it works.In the spring bean xml specify Bean A ref to Bean B and vice versa.

My Spring configuration was like follows:

<context:annotation-config/>

<bean class="Bar" />
<bean class="Foo" />
<bean class="Baz" /> 

Classes are identical to yours

Test app like follows:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/spring/testctx.xml");

        Foo foo = ctx.getBean(Foo.class);
        Baz baz = ctx.getBean(Baz.class);
        Bar bar = ctx.getBean(Bar.class);

        System.out.println(foo.equals(baz.foo));
        System.out.println(foo.equals(bar.foo));
        System.out.println(baz.equals(foo.baz));

        System.out.println(foo.baz.toString());
        System.out.println(baz.toString());
        System.out.println(foo.bar.toString());
        System.out.println(bar.toString());

    }

}

Output from test app like follows:

true
true
true
Baz@8aef2b
Baz@8aef2b
Bar@215bf054
Bar@215bf054

Using 3.0.6 it works perfectly fine (singleton beans are indeed singletons). There might be something else you did not illustrate here messing up your configuration. Of course, as a side note, using default package may cause some misterious magic to happen ;-)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!