有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否是spring的默认作用域单例?

您能解释一下为什么Spring为下面显示的bean的配置创建两个对象,因为默认情况下Spring的默认作用域是singleton吗

Spring配置如下所示:

<bean id="customer" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="100"></property>
    <property name="custName" value="rajasekhar"> </property>
</bean>
<bean id="customer2" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="200"></property> 
    <property name="custName" value="siva"></property> 
</bean>

共 (6) 个答案

  1. # 1 楼答案

    您正在声明同一类的两个bean。这是不一样的

    @Component("springTestClass")
    public class SpringTestClass{
         private int randomNumber = 0;
         public SpringTestClass(){
           randomNumber = new Random().nextInt(2000);
         }
    
         public int getRandomNumber(){
           return this.randomNumber;
         }
    
    }
    

    然后尝试在两个地方访问这个bean,数字将是相同的。但是您所做的是创建两个独立的bean

    如果要检查此功能是否有效,请尝试:

    public class Main{
       public static void main(String[] args){
         ApplicationContext ctx = ....;
         SpringTestClass testObject1 = (SpringTestClass)ctx.getBean("springTestClass");
         SpringTestClass testObject2 = (SpringTestClass)ctx.getBean("springTestClass");
    
        System.out.println(testObject1.getRandomNumber() == testObject2.getRandomNumber());
       }
    }
    

    如果是同一实例,则此代码应返回true; 但在SpringTestClass中,您可以添加@Scope(“prototype”)注释。 输出将为假

  2. # 2 楼答案

    你混淆了两个不同的概念

    spring中的singleton一词用于bean范围,这意味着整个应用程序只创建一次bean

    单例通常指的是GOF模式。它是一种面向对象的模式,保证一个类只存在一个实例(至少在类加载器的范围内)

  3. # 3 楼答案

    Spring的默认作用域单例。只是你对单例的理解与Spring对单例的定义不符

    如果您告诉Spring使用不同的ID和相同的类生成两个单独的bean,那么您将得到两个单独的bean,每个bean都具有单例范围。所有单例作用域的意思是,当您引用具有相同id的对象时,您会得到相同的bean实例

    以下是the Spring documentation defines singleton scope如何:

    Only one shared instance of a singleton bean is managed, and all requests for beans with an id or ids matching that bean definition result in that one specific bean instance being returned by the Spring container.

    Singleton作用域意味着使用相同的id检索相同的bean,仅此而已。如果测试没有两个ID引用同一个类,则会妨碍将映射用作bean,并且使用BeanFactory代理将变得复杂。 对于Spring来说,这将涉及大量的工作,但收效甚微。相反,它信任用户知道他们在做什么

    如果您希望在多个名称之间保持bean的单例性,那么这是可以做到的。可以有多个名称引用同一个bean,这是通过使用alias完成的:

    In a bean definition itself, you can supply more than one name for the bean, by using a combination of up to one name specified by the id attribute, and any number of other names in the name attribute. These names can be equivalent aliases to the same bean, and are useful for some situations, such as allowing each component in an application to refer to a common dependency by using a bean name that is specific to that component itself.

    Specifying all aliases where the bean is actually defined is not always adequate, however. It is sometimes desirable to introduce an alias for a bean that is defined elsewhere. This is commonly the case in large systems where configuration is split amongst each subsystem, each subsystem having its own set of object definitions. In XML-based configuration metadata, you can use the element to accomplish this.

    因此,如果在bean配置中添加名称:

    <bean id="customer" name="customer2" 
        class="jp.ne.goo.beans.Customer">
    </bean>
    

    或者为在别处定义的bean创建别名:

    <alias name="customer" alias="customer2"/>
    

    然后“customer”和“customer2”将引用同一个bean实例

  4. # 4 楼答案

    正如其他人提到的,应该从您发布的代码中创建两个bean。单例定义如下(来自Spring文档:Singleton Scope

    Only one shared instance of a singleton bean is managed, and all requests for beans with an id or ids matching that bean definition result in that one specific bean instance being returned by the Spring container.

    为了更清楚地说明这一点,“共享实例”背后的含义在上文后面的段落中进行了解释:

    all subsequent requests and references for that named bean return the cached object

    创建单例bean时,只实例化和缓存一个bean对象。这只涉及bean,而不涉及bean可能是其实例的任何类。比如说,

    <bean id="myBean" class="myPackage.myClass" />
    
    <bean id="myOtherBean1 class="myPackage.myOtherClass1">
        <property name="beanReference1" ref="myBean" />
    </bean>
    <bean id="myOtherBean2 class="myPackage.myOtherClass2">
        <property name="beanReference2" ref="myBean" />
    </bean>
    

    在这个组合的配置中,“myOtherBean1”和“myOtherBean2”引用了相同的“myBean”bean,因此使用了相同的“myPackage.myClass”实例。如果您更改代码以添加第二个“myPackage.myClass”bean,它将不同于“myBean”

    要完全理解这一点,还可以参考另一个Spring范围:原型。从Prototype Scope的Spring文档中:

    The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made.

    这意味着,如果我们使用与上面相同的SpringXML,“myOtherBean1”和“myOtherBean2”将分别收到各自不同的“myBean”副本,而“myBean”仍然只是“myPackage.myClass”的一个实例

  5. # 5 楼答案

    在Spring中,Singleton指的是每个Spring容器一个bean,而在Java中,Singleton指的是每个类装入器一个对象

    所以Spring singleton与java singleton不同。别把这两者混淆了

  6. # 6 楼答案

    Spring的默认作用域是singleton,它将为所有实例创建一个对象,除非您明确指定要作为原型的作用域。您尚未发布spring配置。请把它贴出来,它会给你一个更好的主意