Spring单例范围的确切含义是什么?

Spring单例范围的确切含义是什么?,spring,spring-ioc,Spring,Spring Ioc,我在applicationContext.xml中为同一个类定义了两个具有不同id名称的bean。它工作得很好,所以我搞不清楚spring单例作用域的确切含义。我的代码如下。我在stackoverflow中讨论了其他一些类似的问题。但我不清楚,因为这些不完全相同的背景和很长的解释 <bean id="a2" class="com.myapp.Address"> <constructor-arg value="Delhi"></constructor-arg&

我在applicationContext.xml中为同一个类定义了两个具有不同id名称的bean。它工作得很好,所以我搞不清楚spring单例作用域的确切含义。我的代码如下。我在stackoverflow中讨论了其他一些类似的问题。但我不清楚,因为这些不完全相同的背景和很长的解释

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
如果你知道它是什么,请和我分享

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
我读到了
1.容器(上下文)的单个实例,
--在我的例子中,是否为我的两个实例创建了两个容器?

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>

spring singleton作用域的工作原理与singleton软件模式()基本相同,其主要思想是,在IOC实例(spring执行上下文)中,每个声明的bean只有一个实例;更简洁地说,每次使用spring注入在代码的任何bean中引用a2、e或e2时,都会有相同的引用,这意味着相同的对象位于相同的内存位置

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
我建议你看看这个:

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
以及以下方面的一些工作示例:

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>

最后一件事,IOC实例与对象实例不同,容器实例与主方法类似,因此所有操作都在其中执行,您可以在单个IOC容器中创建bean并执行所有操作(当然也有一些分布式环境架构,如果你可以有更多的IOC容器实例,但我相信这不是你的情况)

单例范围bean是直截了当的:每个bean实际上是容器中实例化的一个对象(也称为应用程序上下文)

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
在您的示例中,Spring容器将创建2个
Employee
对象(又名bean),分别是
e
e1

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
其他作用域有点棘手。一个bean可以实例化多个对象。例如,如果定义了一个具有原型作用域的bean,那么无论何时从容器中查找该bean,容器都会实例化一个新的对象实例。对于其他作用域,情况类似:容器将基于speci创建一个新实例fic定时(例如,请求范围将导致为每个传入请求创建一个bean,等等)

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>


请注意:不要将此单例与单例设计模式混淆。它们除了“只有一个”特性之外没有任何共同之处。单例设计模式具有许多其他特性(例如,全局可用的查找方法;整个流程空间中只有一个实例;不允许显式实例化等)这与Spring的单例作用域无关

Spring单例作用域意味着Spring容器仅为同一类为不同实例创建一个对象

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
例如,在您的代码中,如果您不向employee的e2对象注入值,并且如果您尝试打印employee类的e和e2的值,则两者都将给出相同的输出

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>
(如果您在同一个XML文件中引用一个bean,那么可以使用
而不是refbean)

<bean id="a2" class="com.myapp.Address">
    <constructor-arg value="Delhi"></constructor-arg>
    <constructor-arg value="DOWN"></constructor-arg>
    <constructor-arg value="India"></constructor-arg>
</bean>


<bean id="e" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a1" />
    </constructor-arg>
</bean>

<bean id="e2" class="com.myapp.Employee">
    <constructor-arg value="12" type="int"></constructor-arg>
    <constructor-arg value="Sonoo"></constructor-arg>
    <constructor-arg>
        <ref bean="a2" />
    </constructor-arg>
</bean>

在上述情况下,e和e2的employee值分别为12和Sonoo。

    <bean id="a2" class="com.myapp.Address">
        <constructor-arg value="Delhi"></constructor-arg>
        <constructor-arg value="DOWN"></constructor-arg>
        <constructor-arg value="India"></constructor-arg>
    </bean>
    
    
    <bean id="e" class="com.myapp.Employee">
        <constructor-arg value="12" type="int"></constructor-arg>
        <constructor-arg value="Sonoo"></constructor-arg>
        <constructor-arg>
            <ref bean="a1" />
        </constructor-arg>
    </bean>
    
    <bean id="e2" class="com.myapp.Employee">
        <constructor-arg value="12" type="int"></constructor-arg>
        <constructor-arg value="Sonoo"></constructor-arg>
        <constructor-arg>
            <ref bean="a2" />
        </constructor-arg>
    </bean>
    
  • Singleton是spring中的默认范围,即每个容器一个bean(或对象)实例
  • 不应该与四人帮的Singleton混淆,它是每个
    类加载器只有一个实例
  • 在您的上下文中,清楚地定义了两个带有地址的雇员bean

我不同意你的观点,认为它的工作原理与单例设计模式几乎相同。实际上,它几乎没有什么共同之处,只是两者都试图做到与“奇点”相关。但是,奇点的上下文和其他特征是完全不同的。vi,它只为两个实例创建一个容器。在代码中,当您为e2赋值时,它实际上会更改e和e2的值,因为它会更改employee对象(仅创建一个对象)的值,这两个对象都共享。