Spring2.x中设置Bean的作用域


在配置文件里声明的Bean时,实际定义的并不是一个Bean实例,而是为Bean创建了一个模板,当通过getBean()调用或其他请求改Bean的时候,Spring将根据Bean的实际作用域返回Bean的实例,在某些情况下默认的作用域并不适合,此时需要为Bean设置一个更适合的作用域。

在Spring2.x里,可以通过<bean>中的scope属性设置作用域,默认情况下Spring只为在Ioc容器里声明的Bean创建一个实例,整个Ioc范围内都共享这个实例,所有后续的getBean()调用和引用该实例,都将返回这个唯一的Bean实例。这个作用域称为singleton,是默认的作用域。

Spring2.x中Bean的几种作用域:

1、singleton--------------为每个Spring Ioc容器创建一个Bean实例;

2、prototype-------------每次请求时都创建一个新的实例;

3、request---------------每个HTTP请求创建一个Bean实例,这个作用域仅在WEB应用程序的上下文中有效;

4、session---------------每个HTTP请求创建一个Bean实例,这个作用域仅在WEB应用程序的上下文中有效;

5、globalSession------为每个全局的HTTP会话创建一个Bean实例,这个作用域尽在门户应用程序的上下文中有效;

下边将用一个商品购物车例子来说明这个Bean的实例作用域:

package com.song.spring.scope;

public abstract class Product {

	private String name;
	private double price;
	
	public Product(){}
	
	public Product(String name, double price){
		this.name = name;
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}
	
	public String toString(){
		return name + " " + price;
	}
}

package com.song.spring.scope;

public class Battery extends Product {

	private boolean rechargeable;
	
	public Battery(){
		super();
	}
	
	public Battery(String name, double price){
		super(name, price);
	}

	public boolean isRechargeable() {
		return rechargeable;
	}

	public void setRechargeable(boolean rechargeable) {
		this.rechargeable = rechargeable;
	}
	
	
}

package com.song.spring.scope;

public class Disc extends Product {

	private int capacity;
	
	public Disc(){
		super();
	}
	
	public Disc(String name, double price){
		super(name, price);
	}

	public int getCapacity() {
		return capacity;
	}

	public void setCapacity(int capacity) {
		this.capacity = capacity;
	}
	
	
}

接下来创建一个无购物车实例;

package com.song.spring.scope;

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> getItem(){
		return items;
	}
}

在classpath:下的xml文件applicationContext.xml中的Bean配置为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
        "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>    
	<bean id="aaa" class="com.song.spring.scope.Battery">
		<property name="name" value="AAA" />
		<property name="price" value="2.5" />
	</bean>
	
	<bean id="cdrw" class="com.song.spring.scope.Disc">
		<property name="name" value="CD-RW" />
		<property name="price" value="1.5" />
	</bean>
	
	<bean id="dvdrw" class="com.song.spring.scope.Disc">
		<property name="name" value="DVD-RW" />
		<property name="price" value="3.0" />
	</bean>
	
	<bean id="shoppingCart" class="com.song.spring.scope.ShoppingCart" />
</beans>

创建一个运行类:

package com.song.spring.scope;

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

public class Main {

	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		Product aaa = (Product)context.getBean("aaa");
		Product cdrw = (Product)context.getBean("cdrw");
		Product dvdrw = (Product)context.getBean("dvdrw");
		
		ShoppingCart cart1 = (ShoppingCart)context.getBean("shoppingCart");
		cart1.addItem(aaa);
		cart1.addItem(cdrw);
		System.out.println("Shopping Cart1 contains:" + cart1.getItem());
		
		ShoppingCart cart2 = (ShoppingCart)context.getBean("shoppingCart");
		cart2.addItem(dvdrw);
		System.out.println("Shopping Cart2 contains:" + cart2.getItem());
	}

}
运行结果为:

Shopping Cart1 contains:[AAA 2.5, CD-RW 1.5]
Shopping Cart2 contains:[AAA 2.5, CD-RW 1.5, DVD-RW 3.0]

显然这不是我们想要的结果;我们所要的是每个顾客各获得一个Bean实例,这时就应该将配置文件中的Bean实例的作用域改为prototype;

<bean id="shoppingCart" class="com.song.spring.scope.ShoppingCart" scope="prototype"/>


再运行所得结果为:

Shopping Cart1 contains:[AAA 2.5, CD-RW 1.5]
Shopping Cart2 contains:[DVD-RW 3.0]

这才是我们想要的结果,完毕!


上一篇:shell 布尔运算符


下一篇:摆脱Spring 定时任务的@Scheduled cron表达式的困扰