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]

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

时间: 2024-09-17 00:41:26

Spring2.x中设置Bean的作用域的相关文章

Spring容器中Bean的作用域

    当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域.Spring支持如下5种作用域: singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例 prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例 request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次

Spring2.0中新的Bean类型实现原理

我们知道,在Spring2.0中,除了singleton及prototype两种类型的Bean以外.默认情况下还增加了request.session及global session三种类型的Bean,增加的三种类型的Bean主要应用于Web应用程序中.本文不打算分析三种类型的Bean的用法,只是简单分析框架的实现原理. Spring2.0中新增了一个用来表示Bean范围的Scope接口 public interface Scope { Object get(String name, ObjectF

Spring中Bean的作用域差别

我觉得servlet和spring交叉起来,理解得快. Bean的作用域中,prototype和singleton作用域效果不一样,前者每次都会有新的实例,而后者始终一个实例 . 所以,java.util.date在prototype时,会输出不同的时间,而singleton时只会输出同一个时间. config.xml: <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http:

singleton-spring容器中bean的作用域?

问题描述 spring容器中bean的作用域? 作用域的作用??求个通俗点的例子关于singleton和prototype区别 解决方案 spring管理bean作用域Spring中bean的作用域及Spring容器初始化的相关问题Spring中Bean的作用域和自动装配 解决方案二: prototype 是每次访问拿到一个实例,比如说new Date();这种方式 singleton 是全局共享一个实例,比如Calender.getInstance();这种方式 解决方案三: singleto

spring之bean的作用域scope的值的详解

今天研究了一下scope的作用域.默认是单例模式,即 scope="singleton".另外scope还有prototype.request.session.global session作用域.scope="prototype"多例.再配置bean的作用域时,它的头文件形式如下: 如何使用spring的作用域: <bean id="role" class="spring.chapter2.maryGame.Role"

Spring中管理Bean依赖注入之后和Bean销毁之前的行为

    对于Singleton作用域的Bean,Spring容器将会跟踪它们的生命周期,容器知道何时实例化结束.何时销毁.Spring可以管理Bean在实例化结束之后和Bean销毁之前的行为. Bean依赖关系注入之后的行为:     Spring提供了两种方式在Bean全部属性设置成功后执行特定的行为: 在Spring配置文件中使用init-method属性:这个属性指定某个方法在Bean全部依赖关系设置结束后自动执行.这个方法写在Bean里面.使用这种方法不需要将代码与Spring耦合在一起

Spring Bean的作用域(转)

  Spring Bean的作用域 .singleton  [单例] eg:<bean id="personService" class="com.yinger.service.impl.PersonServiceBean" scope="singleton"></bean> 在每个Spring IoC容器中一个bean定义只有一个对象实例. 请注意Spring的singleton bean概念与"四人帮&quo

想讨论一下.struts+spring+hibernate的bean的作用域问题,也就是&amp;amp;lt;bean

问题描述 想讨论一下.struts+spring+hibernate的bean的作用域问题,也就是<bean scope="">的设置从表示层开始:1.Struts Action对应的bean作用域2.业务层的Service类的bean作用域3.数据存储层的DAO类的bean作用域4.实体层的Bean的作用域. 解决方案 1.Struts Action对应的bean作用域 scope=prototype2.业务层的Service类的bean作用域 scope=prototy

asp中设置session过期时间方法总结

 如果程序中没有设置session的过期时间,那么session过期时间就会按照IIS设置的过期时间来执行,IIS中session默认过期时间为20分钟,IIS中session时间可以更改   如果程序中设置了session过期时间,那么,即使你将IIS中session时间设置100小时也没有用,因为程序会首先按照程序中设置,只有程序没设置的情况下才会按照IIS设置的 时间设置要放在前面 例如  代码如下   Session.Timeout=30 'SEESION有效时间为30分钟  Sessi