Spring Bean 作用域

  • Bean 作用域

    定义<bean>时,可以选择声明bean的作用域。例如,要强制Spring每次需要一个新的bean实例时,应将bean的scope属性声明为prototype。同样,如果您希望Spring每次需要一个实例时都返回相同的bean实例,则应将bean的scope属性声明为singleton。Spring框架支持以下五个作用域,其中三个仅在使用Web感知的ApplicationContext时可用。
    属性 描述
    singleton 这会将bean定义的作用域限定为每个Spring IoC容器一个实例(默认)。
    prototype 这将单个bean定义的作用域限定为具有任意数量的对象实例。
    request 这将bean定义的作用域限定为HTTP请求。 仅在可感知网络的Spring ApplicationContext上下文中有效。
    session 这将bean定义的作用域限定为HTTP会话。 仅在可感知网络的Spring ApplicationContext上下文中有效。
    global-session 这将bean定义的作用域限定为全局HTTP会话。 仅在可感知网络的Spring ApplicationContext上下文中有效。
    在本章中,我们将讨论前两个作用域,而其余三个将在讨论有关Web的Spring ApplicationContext时进行讨论。
  • singleton作用域

    如果将作用域设置为singleton,则Spring IoC容器将创建该bean定义所定义的对象的一个​​实例。将单个实例存储在此类单例bean的高速缓存中,并且对该命名bean的所有后续请求和引用都返回该高速缓存的对象。默认作用域始终为单例。但是,当您只需要一个bean的一个实例时,可以在bean配置文件中将scope属性设置为singleton,如以下代码片段所示
    <!-- A bean definition with singleton scope -->
    <bean id = "..." class = "..." scope = "singleton">
       <!-- collaborators and configuration for this bean go here -->
    </bean>
    示例::
    假设我们拥有一个运行良好的Eclipse IDE,并采取以下步骤来创建一个Spring应用程序:
    1. 创建一个名称为SpringExample的项目,并在创建的项目的src文件夹下创建一个包com.jc2182
    2. 使用“添加外部JAR”选项添加所需的Spring库,如“Spring Hello World示例”一章中所述。
    3. 在com.jc2182包下创建Java类HelloWorld和MainApp。
    4. 在src文件夹下创建Beans配置文件Beans.xml。
    5. 最后一步是创建所有Java文件和Bean配置文件的内容,然后按以下说明运行应用程序。
    这是HelloWorld.java文件的内容:
    package com.jc2182;
    
    public class HelloWorld {
       private String message;
    
       public void setMessage(String message){
          this.message  = message;
       }
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
    }
    以下是MainApp.java文件的内容:
    package com.jc2182;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
          HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
    
          objA.setMessage("I'm object A");
          objA.getMessage();
    
          HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
          objB.getMessage();
       }
    }
    以下是单例作用域所需的配置文件Beans.xml:
    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.jc2182.HelloWorld" scope = "singleton">
       </bean>
    
    </beans>
    完成创建源和Bean配置文件后,让我们运行该应用程序。如果您的应用程序一切正常,它将显示以下消息:
    Your Message : I'm object A
    Your Message : I'm object A
    表示了两个对象,就是一个同一个实例。
  • prototype作用域

    如果将范围设置为prototype,则每次提出对该特定bean的请求时,Spring IoC容器都会创建该对象的新bean实例。通常,对所有有状态的bean使用prototype作用域,对无状态的bean使用singleton范围。要定义prototype作用域,可以在bean配置文件中将scope属性设置为prototype,如以下代码片段所示
    <!-- A bean definition with prototype scope -->
    <bean id = "..." class = "..." scope = "prototype">
       <!-- collaborators and configuration for this bean go here -->
    </bean>
    示例::
    假设我们拥有一个运行良好的Eclipse IDE,并采取以下步骤来创建一个Spring应用程序:
    1. 创建一个名称为SpringExample的项目,并在创建的项目的src文件夹下创建一个包com.jc2182
    2. 使用“添加外部JAR”选项添加所需的Spring库,如“Spring Hello World示例”一章中所述。
    3. 在com.jc2182包下创建Java类HelloWorld和MainApp。
    4. 在src文件夹下创建Beans配置文件Beans.xml。
    5. 最后一步是创建所有Java文件和Bean配置文件的内容,然后按以下说明运行应用程序。
    这是HelloWorld.java文件的内容:
    package com.jc2182;
    
    public class HelloWorld {
       private String message;
    
       public void setMessage(String message){
          this.message  = message;
       }
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
    }
    以下是MainApp.java文件的内容:
    package com.jc2182;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
          HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
    
          objA.setMessage("I'm object A");
          objA.getMessage();
    
          HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
          objB.getMessage();
       }
    }
    以下是原型作用域所需的配置文件Beans.xml:
    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.jc2182.HelloWorld" scope = "prototype">
       </bean>
    
    </beans>
    完成创建源和Bean配置文件后,让我们运行该应用程序。如果您的应用程序一切正常,它将显示以下消息:
    Your Message : I'm object A
    null
    表示了两个对象,不是一个同一个实例。第一个对象设置了值,第二个对象是新的实例并没有设置值。