spring中bean的scope屬性,有如下5種類型:
- singleton 表示在spring容器中的單例,通過spring容器獲得該bean時總是返回唯一的實例
- prototype表示每次獲得bean都會生成一個新的對象
- request表示在一次http請求內有效(只適用於web應用)
- session表示在一個用戶會話內有效(只適用於web應用)
- globalSession表示在全局會話內有效(只適用於web應用)
在多數情況,我們只會使用singleton和prototype兩種scope,如果在spring配置文件內未指定scope屬性,默認為singleton。
下面我們用一個示例來說明singleton和prototype兩種scope的區別。
添加java類Person,Person的內容如下:
package cn.outofmemory.spring; public class Person { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Person類是一個POJO類,我們不需要他做任何事情,只是為了證明prototype和singleton兩種scope的異同之處。
我們還需要一個App類,他的代碼如下:
package cn.outofmemory.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) { ApplicationContext appContext = new ClassPathXmlApplicationContext("/spring.xml"); Person p1 = appContext.getBean(Person.class); System.out.println("p1's identityHashCode is " + System.identityHashCode(p1)); Person p2 = appContext.getBean(Person.class); System.out.println("p2's identityHashCode is " + System.identityHashCode(p2)); } }
在App類中的main方法中,首先我們初始化了ApplicationContext的實例,然后分別獲得兩次Person bean的實例p1,p2並分別輸出其identityHashCode,如果兩個對象是同一個對象,那么他們的identityHashCode應該是一致的。
添加source folder:src/main/conf,並新建spring配置文件spring.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="cn.outofmemory.spring.Person"> <property name="id" value="1"/> <property name="name" value="Jim"/> </bean> </beans>
在此配置文件中我們定義了Person bean,沒有指定其scope,這時候bean的scope為默認的singleton,也就是單例,此時App類的輸出應該是兩個相同的identityHashcode,我們運行程序看輸出的結果:
p1's identityHashCode is 23954271 p2's identityHashCode is 23954271
<bean class="cn.outofmemory.spring.Person" scope="prototype"> <property name="id" value="1"/> <property name="name" value="Jim"/> </bean>
再次運行程序,輸出結果如下:
p1's identityHashCode is 23954271 p2's identityHashCode is 13359324
可以看到p1和p2是兩個不同的值,這說明scope是prototype的情況下,同一個bean定義會返回不同的對象。
我們也可以通過Scope注解來指定java bean的scope,我們給Person類添加如下注解:
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") public class Person { ....省略 }
@Component注解告訴spring,要加載此類,Scope注解bean的scope是prototype。
我們修改spring.xml配置文件,使用context:component-scan節點,讓spring通過注解加載bean。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="cn.outofmemory.spring"></context:component-scan> </beans>
再次運行程序,將輸出:
p1's identityHashCode is 33212498 p2's identityHashCode is 24480977
可以看到使用Scope注解指定prototype scope后,兩個Person對象是兩個不同的對象。
原文地址 : http://outofmemory.cn/java/spring/spring-bean-scope