赞
踩
声明:
这是转载的,内容源自网络整理而成。
----------------------------------------------------------------------------------------
【正文】
Spring容器最初提供了两种bean的scope类型:singleton和prototype,但发布2.0以后,又引入了另外三种scope类型:request、session和global session,这三种只能在web 应用中才可以使用。
一、基础概念
singleton: 在Spring的IoC容器中只存在一个对象实例,所有该对象的引用都共享这个实例。Spring 容器只会创建该bean定义的唯一实例,这个实例会被保存到缓存中,并且对该bean的所有后续请求和引用都将返回该缓存中的对象实例,一般情况下,无状态的bean使用该scope。
prototype:每次对该bean的请求都会创建一个新的实例,一般情况下,有状态的bean使用该scope。
request:每次http请求将会有各自的bean实例,类似于prototype。
session:在一个http session中,一个bean定义对应一个bean实例。
global session:在一个全局的http session中,一个bean定义对应一个bean实例。典型情况下,仅在使用portlet context的时候有效。
其次说明spring的默认scope(bean作用域)是singleton
二、自定义scope类型
在spring2.0中作用域是可以任意扩展的,你可以自定义作用域,甚至你也可以重新定义已有的作用域(但是你不能覆盖singleton和 prototype),spring的作用域由接口org.springframework.beans.factory.config.Scope来定 义,自定义自己的作用域只要实现该接口即可,下面给个实例:
我们建立一个线程的scope,该scope在表示一个线程中有效,代码如下:
- publicclass MyScope implements Scope {
- privatefinal ThreadLocal threadScope = new ThreadLocal() {
- protected Object initialValue() {
- returnnew HashMap();
- }
- };
- public Object get(String name, ObjectFactory objectFactory) {
- Map scope = (Map) threadScope.get();
- Object object = scope.get(name);
- if(object==null) {
- object = objectFactory.getObject();
- scope.put(name, object);
- }
- return object;
- }
- public Object remove(String name) {
- Map scope = (Map) threadScope.get();
- return scope.remove(name);
- }
- publicvoid registerDestructionCallback(String name, Runnable callback) {
- }
- public String getConversationId() {
- // TODO Auto-generated method stub
- returnnull;
- }
- }
①问:scope类型什么时候声明为singleton,何时声明为prototype?
默认scope是singleton。
无状态的bean使用该scope。
有状态的bean使用prototype。
有状态和无状态会话bean的本质区别是它们的生命期。
bean保持了用户的信息,即“有状态”
无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。
②
在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”;
但是对那些Dao的实现类推介scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些。
③比较:
用singleton 的性能要高一些 ,因为只有一个实例;
④实际应用举例:
之前在开发过程中遇到了一个问题,当request发起下一个请求的时候,action中的属性值并没有清除,而是继续采用上次使用过的参数值进行查询并响应,导致数据查询不真实或失败。对此,有同事告诉我说,需要在spring配置文件的bean中添加属性scope=prototype。结果还真的有用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。