能够创建弹簧单例的多个实例

时间:2018-03-27 12:02:01

标签: java spring

我有一个测试类,我已经在我的spring bean配置文件中定义了它,如下所示:

   <bean id = "springsingleton1" class = "com.learn.stackoverflow.general.SpringSingleton"/>
   <bean id = "springsingleton2" class = "com.learn.stackoverflow.general.SpringSingleton" scope="prototype"/>
   <bean id = "springsingleton3" class = "com.learn.stackoverflow.general.SpringSingleton"/>

我的期望是这会引发一些异常,因为我首先定义了一个单例bean,然后我尝试创建相同的另一个原型,或者如果没有抛出异常,那么我将总是得到所有3的相同实例案件,但我得到不同的实例。以下是代码:

    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\E_Drive\\Projects\\Workspace\\Test\\CS101\\src\\com\\learn\\stackoverflow\\general\\bean.xml");
    SpringSingleton springSingleton11 = (SpringSingleton) applicationContext.getBean("springsingleton1");
    SpringSingleton springSingleton21 = (SpringSingleton) applicationContext.getBean("springsingleton2");
    SpringSingleton springSingleton22 = (SpringSingleton) applicationContext.getBean("springsingleton2");
    SpringSingleton springSingleton3 = (SpringSingleton) applicationContext.getBean("springsingleton3");
    SpringSingleton springSingleton12 = (SpringSingleton) applicationContext.getBean("springsingleton1");

    System.out.println("springSingleton11 : " + springSingleton11.hashCode());
    System.out.println("springSingleton21 : " + springSingleton21.hashCode());
    System.out.println("springSingleton22 : " + springSingleton22.hashCode());
    System.out.println("springSingleton3 : " + springSingleton3.hashCode());
    System.out.println("springSingleton12 : " + springSingleton12.hashCode());

输出:

springSingleton11 : 1658926803
springSingleton21 : 210652080
springSingleton22 : 1652149987
springSingleton3 : 1107730949
springSingleton12 : 1658926803

我如何获得多个实例,Spring没有实施单例?

请注意我已阅读this question并且我没有回答我的疑问。

3 个答案:

答案 0 :(得分:3)

来自Spring documentation

  

Spring的单例bean概念与Singleton不同   四人帮(GoF)模式书中定义的模式。 GoF   Singleton硬编码对象的范围,使得只有一个   每个ClassLoader创建一个特定类的实例。范围   Spring单例的最好描述为每个容器和每个   bean。这意味着如果你为一个特定的类定义一个bean   一个Spring容器,然后Spring容器创建一个和   只有该bean定义定义的类的一个实例。该   单例范围是Spring中的默认范围。

所以,Spring并没有确保只有这样一个类的一个实例,它只能确保当你调用一个单例bean时(例​​如,根据你的例子反复得到{{1}然后你得到相同的实例。

解决方法是,不要在bean配置文件中定义bean,而是将您的类注释为springsingleton1,然后始终使用自动装配来获取此类的实例,但您必须严格确保没有在你的bean配置文件中定义这个bean,因为如果你这样做(与你在问题中所做的相同),那么即使你有@Scope("singleton")注释仍然可以有多个实例。

答案 1 :(得分:0)

Spring没有强制执行Singleton设计模式,scope=singleton仅仅意味着无论何时引用bean(例如,通过它的id),您都将从Spring容器中获取相同的实例。

一个例子:

<bean id="a" class="MyClass1" scope="prototype">
    <property name="b" ref="b" />
</bean>
<bean id="b" class="MyClass2" scope="singleton" />

在这样的配置中,每当你引用bean MyClass1或者从容器中请求bean时,你都会获得a的新实例,但每个实例都会指向同一个MyClass2属性中b的实例。

答案 2 :(得分:0)

您有两个单身豆springsingleton1springsingleton3。他们共享同一个班级,但豆子本身就是单身人士。在询问其中任何一个时,您将始终收到相同的对象,但对象本身并不相同。

单例bean与单例类不同。

原型的运作方式就像你期望的那样。