现在的位置: 首页 > 综合 > 正文

Spring攻略学习笔记(2.06)——设置Bean作用域

2013年09月08日 ⁄ 综合 ⁄ 共 3361字 ⁄ 字号 评论关闭

     一、知识点  

        当你在配置文件中声明Bean时,实际上定义了Bean创建的一个模板,而不是真正的Bean实例。当getBean()方法或者其它Bean的引用请求Bean时,Spring将根据Bean作用域(Scope)决定该返回哪个Bean实例。有时候必须为Bean设置正确的作用域而不是使用默认的(singleton)作用域。

        在Spring2.x或更高版本中,Bean的作用域在<bean>元素的scope属性中设置默认情况下,Spring为IoC容器中声明的每个Bean创建一个实例,这个实例将在整个IoC容器的范围内共享。所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。这种作用域称作singleton,是所有Bean的默认作用域。下面是Spring中所有有效的Bean作用域。
        Singleton:每个Spring IoC容器创建单个bean实例。
        Prototype:每次请求时创建一个新的Bean实例。
        Request:每个HTTP请求创建一个Bean实例,仅在Web应用上下文中有效。
        Session:每个HTTP会话创建一个Bean实例,仅在Web应用上下文中有效。
        GlobalSession:为每个全局HTTP会话创建一个Bean实例,仅在portal应用上下文中有效。

二、代码示例

        创建ShoppingCart类

package com.jackie.codeproject.springrecipesnote.springadvancedioc;

import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {
	private List<Product> items = new ArrayList<Product>();

	public void addItem(Product item) {
		items.add(item);
	}

	public List<Product> getItems() {
		return items;
	}
}

       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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="aaa" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.Battery">
    	<property name="name" value="AAA" />
    	<property name="price" value="2.5" />
    </bean>
    
    <bean id="cdrw" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.Battery">
    	<property name="name" value="CD-RW" />
    	<property name="price" value="1.5" />
    </bean>
    
    <bean id="dvdrw" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.Battery">
    	<property name="name" value="DVD-RW" />
    	<property name="price" value="3.0" />
    </bean>
    
    <bean id="shoppingCart" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.ShoppingCart" />
</beans>

   测试类

package com.jackie.codeproject.springrecipesnote.springadvancedioc;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanScopeTest {
	private ApplicationContext applicationContext;
	
	@Test
	public void testBeanScope(){
		applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Product aaa = (Product) applicationContext.getBean("aaa");
		Product cdrw = (Product) applicationContext.getBean("cdrw");
		Product dvdrw = (Product) applicationContext.getBean("dvdrw");
		ShoppingCart shoppingCart1 = (ShoppingCart) applicationContext.getBean("shoppingCart");
		shoppingCart1.addItem(aaa);
		shoppingCart1.addItem(cdrw);
		System.out.println("Shopping cart 1 contains " + shoppingCart1.getItems());
		ShoppingCart cart2 = (ShoppingCart) applicationContext.getBean("shoppingCart");
		cart2.addItem(dvdrw);
		System.out.println("Shopping cart 2 contains " + cart2.getItems());	
	}
}

运行结果如下:

Shopping cart 1 contains [AAA:2.5, CD-RW:1.5]
Shopping cart 2 contains [AAA:2.5, CD-RW:1.5, DVD-RW:3.0]

可以看到两个取得的是同一个购物车实例,这是因为Spring默认的Bean作用域是singleton,意味着Spring为每个IoC容器创建一个购物车实例:

<bean id="shoppingCart" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.ShoppingCart" scope="singleton" />

如果你期望每位顾客调用getBean()方法时获得不同的购物车实例,可以将shoppingCart这个Bean的scope属性改为prototype。之后Spring将为每个getBean()方法调用和其它Bean中的引用创建一个新的Bean实例。

<bean id="shoppingCart" class="com.jackie.codeproject.springrecipesnote.springadvancedioc.ShoppingCart" scope="prototype" />

再次运行测试类,结果如下:

Shopping cart 1 contains [AAA:2.5, CD-RW:1.5]
Shopping cart 2 contains [DVD-RW:3.0]

抱歉!评论已关闭.