Spring的bean作用域最初只有singleton和prototype,spring2.0后又添加了request、session和global session类型,不过后面三种只能在web应用上使用。默认是singleton。scope的设置如下:
<bean id="scopeBean" class="..." scope="prototype">
1.singleton
标记为singleton的对象在Spring容器中只存在一个实例,所有对该对象的引用将共享这个对象。并且几乎与容器拥有相同的寿命,从第一次被请求而初始化后,将一直存活到容器的退出。
2.prototype
在拥有prototype的scope的bean定义,容器在接受到该类型的请求时都会每次重新生成一个新的实例。虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不再拥有当前返回对象的引用,请求方需要自己负责当前返回对象的后继生命周期的管理工作,包括该对象的销毁。也就是说,容器每次返回给请求方一个新的对象实例之后,就任由这个对象实例“自生自灭”了。
3.request
XmlWebApplicationContext 会为每个HTTP请求创建一个全新的 RequestProcessor 对象供当前请求使用,当请求结束后,该对象实例的生命周期即结束了。当同时有10个HTTP请求进来的时候,容器会分别针对这10个请求返回10个全新的 RequestProcessor 对象实例,且它们之间互不干扰。从不是很严格的意义上说,request可以看作prototype的一种特例,除了场景更加具体之外,语意上差不多。
4.session
Spring容器会为每个独立的session创建属于它们自己的全新的 UserPreferences 对象实例。与request相比,除了拥有session 的scope的bean的实例具有比request 的scope的bean可能有更长的存活时间,其他方面没什么差别。
5.globalSession
global session只有应用在基于portlet的Web应用程序中才有意义,它映射到portlet的全局范围的session。如果在普通的基于servlet的Web应用中使用了这个类型的scope,容器会将其作为普通的session类型的scope对待。
6.自定义的scope
要自定义scope必须实现org.springframework.beans.factory.config.Scope接口,该接口的定义如下:
public interface Scope { Object get(String name, ObjectFactory objectFactory); Object remove(String name); void registerDestructionCallback(String name, Runnable callback); String getConversationId(); }
其中的get和remove方法必须实现。实现该接口后必须注册到容器后才能使用。通常使用ConfigurableBeanFactory的registerScope方法注册。如:
//threadScope类实现了Scope的接口
Scope threadScope=new ThreadScope();
ConfigurableBeanFactory.registerScope("thread",threadScope");
//然后bean可以使用名为thread类型的scope