Spring Bean 作用域

2022-05-21 15:21 更新

當(dāng)在 Spring 中定義一個 bean 時,你必須聲明該 bean 的作用域的選項。例如,為了強(qiáng)制 Spring 在每次需要時都產(chǎn)生一個新的 bean 實例,你應(yīng)該聲明 bean 的作用域的屬性為 prototype。同理,如果你想讓 Spring 在每次需要時都返回同一個bean實例,你應(yīng)該聲明 bean 的作用域的屬性為 singleton。

Spring 框架支持以下五個作用域,分別為 singleton、prototype、request、session 和 global session,5種作用域說明如下所示,

注意,如果你使用 web-aware ApplicationContext 時,其中三個是可用的。    

作用域 描述
singleton

在spring IoC容器僅存在一個Bean實例,Bean以單例方式存在,默認(rèn)值

prototype 每次從容器中調(diào)用Bean時,都返回一個新的實例,即每次調(diào)用getBean()時,相當(dāng)于執(zhí)行newXxxBean()
request 每次HTTP請求都會創(chuàng)建一個新的Bean,該作用域僅適用于WebApplicationContext環(huán)境
session 同一個HTTP Session共享一個Bean,不同Session使用不同的Bean,僅適用于WebApplicationContext環(huán)境
global-session 一般用于Portlet應(yīng)用環(huán)境,該作用域僅適用于WebApplicationContext環(huán)境

本章將討論前兩個范圍,當(dāng)我們將討論有關(guān) web-aware Spring ApplicationContext 時,其余三個將被討論。

singleton 作用域:

singleton 是默認(rèn)的作用域,也就是說,當(dāng)定義 Bean 時,如果沒有指定作用域配置項,則 Bean 的作用域被默認(rèn)為 singleton。

當(dāng)一個bean的作用域為 Singleton,那么 Spring IoC 容器中只會存在一個共享的 bean 實例,并且所有對 bean 的請求,只要 id 與該 bean 定義相匹配,則只會返回 bean 的同一實例。

也就是說,當(dāng)將一個 bean 定義設(shè)置為 singleton 作用域的時候,Spring IoC 容器只會創(chuàng)建該 bean 定義的唯一實例。

Singleton 是單例類型,就是在創(chuàng)建起容器時就同時自動創(chuàng)建了一個 bean 的對象,不管你是否使用,他都存在了,每次獲取到的對象都是同一個對象。注意,Singleton 作用域是 Spring 中的缺省作用域。你可以在 bean 的配置文件中設(shè)置作用域的屬性為 singleton,如下所示:

<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
    <!-- collaborators and configuration for this bean go here -->
</bean>

例子

我們在適當(dāng)?shù)奈恢檬褂?Eclipse IDE,然后按照下面的步驟來創(chuàng)建一個 Spring 應(yīng)用程序:

步驟 描述
1 創(chuàng)建一個名稱為 SpringExample 的項目,并且在創(chuàng)建項目的 src 文件夾中創(chuàng)建一個包 com.tutorialspoint。
2 使用 Add External JARs 選項,添加所需的 Spring 庫,在 Spring Hello World Example 章節(jié)解釋。
3 com.tutorialspoint 包中創(chuàng)建 Java 類 HelloWorldMainApp
4 src 文件夾中創(chuàng)建 Beans 配置文件 Beans.xml。
5 最后一步是創(chuàng)建的所有 Java 文件和 Bean 配置文件的內(nèi)容,并運(yùn)行應(yīng)用程序,解釋如下。

這里是 HelloWorld.java 文件的內(nèi)容:

package com.tutorialspoint;
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 文件的內(nèi)容:

package com.tutorialspoint;
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();
   }
}

下面是 singleton 作用域必需的配置文件 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.tutorialspoint.HelloWorld" 
      scope="singleton">
   </bean>

</beans>

一旦你創(chuàng)建源代碼和 bean 配置文件完成后,我們就可以運(yùn)行該應(yīng)用程序。如果你的應(yīng)用程序一切都正常,將輸出以下信息:

Your Message : I'm object A
Your Message : I'm object A

prototype 作用域

當(dāng)一個 bean 的作用域為 Prototype,表示一個 bean 定義對應(yīng)多個對象實例。Prototype 作用域的 bean 會導(dǎo)致在每次對該 bean 請求(將其注入到另一個 bean 中,或者以程序的方式調(diào)用容器的 getBean() 方法)時都會創(chuàng)建一個新的 bean 實例。Prototype 是原型類型,它在我們創(chuàng)建容器的時候并沒有實例化,而是當(dāng)我們獲取bean的時候才會去創(chuàng)建一個對象,而且我們每次獲取到的對象都不是同一個對象。根據(jù)經(jīng)驗,對有狀態(tài)的 bean 應(yīng)該使用 prototype 作用域,而對無狀態(tài)的bean則應(yīng)該使用 singleton 作用域。

為了定義 prototype 作用域,你可以在 bean 的配置文件中設(shè)置作用域的屬性為 prototype,如下所示:

<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
   <!-- collaborators and configuration for this bean go here -->
</bean>

例子

我們在適當(dāng)?shù)奈恢檬褂?Eclipse IDE,然后按照下面的步驟來創(chuàng)建一個 Spring 應(yīng)用程序:

步驟 描述
1 創(chuàng)建一個名稱為 SpringExample 的項目,并且在創(chuàng)建項目的 src 文件夾中創(chuàng)建一個包com.tutorialspoint。
2 使用 Add External JARs 選項,添加所需的 Spring 庫,解釋見 Spring Hello World Example 章節(jié)。
3 com.tutorialspoint 包中創(chuàng)建 Java 類 HelloWorldMainApp。
4 src 文件夾中創(chuàng)建 Beans 配置文件Beans.xml。
5 最后一步是創(chuàng)建的所有 Java 文件和 Bean 配置文件的內(nèi)容,并運(yùn)行應(yīng)用程序,解釋如下所示。

這里是 HelloWorld.java 文件的內(nèi)容:

package com.tutorialspoint;

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 文件的內(nèi)容:

package com.tutorialspoint;
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();
   }
}

下面是 prototype 作用域必需的配置文件 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.tutorialspoint.HelloWorld" 
      scope="prototype">
   </bean>

</beans>

一旦你創(chuàng)建源代碼和 Bean 配置文件完成后,我們就可以運(yùn)行該應(yīng)用程序。如果你的應(yīng)用程序一切都正常,將輸出以下信息:

Your Message : I'm object A
Your Message : null
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號