當(dāng)在 Spring 中定義一個(gè) 時(shí),你必須聲明該 bean 的作用域的選項(xiàng)。例如,為了強(qiáng)制 Spring 在每次需要時(shí)都產(chǎn)生一個(gè)新的 bean 實(shí)例,你應(yīng)該聲明 bean 的作用域的屬性為 prototype。同理,如果你想讓 Spring 在每次需要時(shí)都返回同一個(gè)bean實(shí)例,你應(yīng)該聲明 bean 的作用域的屬性為 singleton。
Spring 框架支持以下五個(gè)作用域,如果你使用 web-aware ApplicationContext 時(shí),其中三個(gè)是可用的。
作用域 | 描述 |
---|---|
singleton | 該作用域?qū)?bean 的定義的限制在每一個(gè) Spring IoC 容器中的一個(gè)單一實(shí)例(默認(rèn))。 |
prototype | 該作用域?qū)我?bean 的定義限制在任意數(shù)量的對(duì)象實(shí)例。 |
request | 該作用域?qū)?bean 的定義限制為 HTTP 請(qǐng)求。只在 web-aware Spring ApplicationContext 的上下文中有效。 |
session | 該作用域?qū)?bean 的定義限制為 HTTP 會(huì)話。 只在web-aware Spring ApplicationContext的上下文中有效。 |
global-session | 該作用域?qū)?bean 的定義限制為全局 HTTP 會(huì)話。只在 web-aware Spring ApplicationContext 的上下文中有效。 |
本章將討論前兩個(gè)范圍,當(dāng)我們將討論有關(guān) web-aware Spring ApplicationContext 時(shí),其余三個(gè)將被討論。
如果作用域設(shè)置為 singleton,那么 Spring IoC 容器剛好創(chuàng)建一個(gè)由該 bean 定義的對(duì)象的實(shí)例。該單一實(shí)例將存儲(chǔ)在這種單例 bean 的高速緩存中,以及針對(duì)該 bean 的所有后續(xù)的請(qǐng)求和引用都返回緩存對(duì)象。
默認(rèn)作用域是始終是 singleton,但是當(dāng)僅僅需要 bean 的一個(gè)實(shí)例時(shí),你可以在 bean 的配置文件中設(shè)置作用域的屬性為 singleton,如下所示:
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
<!-- collaborators and configuration for this bean go here -->
</bean>
我們?cè)谶m當(dāng)?shù)奈恢檬褂?Eclipse IDE,然后按照下面的步驟來創(chuàng)建一個(gè) Spring 應(yīng)用程序:
步驟 | 描述 |
---|---|
1 | 創(chuàng)建一個(gè)名稱為 SpringExample 的項(xiàng)目,并且在創(chuàng)建項(xiàng)目的 src 文件夾中創(chuàng)建一個(gè)包 com.tutorialspoint。 |
2 | 使用 Add External JARs 選項(xiàng),添加所需的 Spring 庫,在 Spring Hello World Example 章節(jié)解釋。 |
3 | 在 com.tutorialspoint 包中創(chuàng)建 Java 類 HelloWorld 和 MainApp。 |
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
如果作用域設(shè)置為 prototype,那么每次特定的 bean 發(fā)出請(qǐng)求時(shí) Spring IoC 容器就創(chuàng)建對(duì)象的新的 Bean 實(shí)例。一般說來,滿狀態(tài)的 bean 使用 prototype 作用域和沒有狀態(tài)的 bean 使用 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>
我們?cè)谶m當(dāng)?shù)奈恢檬褂?Eclipse IDE,然后按照下面的步驟來創(chuàng)建一個(gè) Spring 應(yīng)用程序:
步驟 | 描述 |
---|---|
1 | 創(chuàng)建一個(gè)名稱為 SpringExample 的項(xiàng)目,并且在創(chuàng)建項(xiàng)目的 src 文件夾中創(chuàng)建一個(gè)包com.tutorialspoint。 |
2 | 使用 Add External JARs 選項(xiàng),添加所需的 Spring 庫,解釋見 Spring Hello World Example 章節(jié)。 |
3 | 在 com.tutorialspoint 包中創(chuàng)建 Java 類 HelloWorld 和 MainApp。 |
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