bean 的 Scope
BeanFactory 除了拥有 IoC Service Provider 的职责,作为一个轻量级容器,它还有着其他的一些职责,其中就包括生命周期
- singleton
配置中的bean可以看作一个模板,容器会根据这个模板来构造对象。但是要根据这个模板构造多少对象实例,又该让这些构造完的对象实例存活多久,则由容器根据bean定义的scope语意来决定。标记为拥有singleton scope 的对象定义,在Spring 的IoC容器中存在一个实例,所有对该对象的引用将共享这个实例。该实例从容器启动,并因为第一次被请求而初始化之后,将一直存活到容器退出。也就是说,它与IoC容器“几乎”拥有相同的寿命
需要注意的一点是,不要因为名字的原因而与GoF所提出的Singleton模式相搞混,二者的语意是不同的;标记为singleton的bean是由容器来保证这种类型的bean在同一个容器中之存在一个共享实例;而Singleton模式则是保证同一个Classloader中只存在一个这种类型的实例。
可以从两方面看待singleton类型的bean所具有的特性:
2.prototype
容器在接到该类型对象的请求的时候,会每次都重新生成一个新的对象实例给请求方。虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不再拥有当前返回对象的引用,请求方需要自己负责当前返回对象的后继生活周期的管理工作,包括该对象的销毁。也就是说,容器每次返回给请求方一个新的对象实例之后,就任由这个对象实例“自生自灭”了。
3.request、session和global session
request、session和global session 只适用于Web 应用程序,通常是与XmlWebApplicationContext共同使用。
- request
spring容器,即XmlWebApplication会为每个Http请求创建一个全新的RequestProcessor对象供当前请求使用,当请求结束后,该对象实例的生命周期即告结束。当同时有10个HTTP请求进来的时候,容器会分别针对这10个请求返回10个全新的RequestProcessor对象实例,且它们之间互不干扰。从不是很严格的意义上说,request 可以看作 prototype 的一种特例,除了场景更加具体之外,语义上差不多。 - session
session 中最普遍的信息就是用户的登录信息, Spring 会为贝格独立的session创建属于他们自己的全新的UserPerferences 对象实例。与request相比,除了拥有session scope 的bean 的实例具有比request scope 的bean 可能更长的存活时间,其他方便真是没什么差别。 - global session
global session 是用在 portlet 中的 global session 在一般的servlet 中 被作为普通的session 对待
自定义scope类型
在 Spring 2.0 之后的版本中,容器提供了对scope的扩展点,这样,你可以根据自己的需要或者应用的场景,来添加自定义的scope类型。需要说明的是,默认的singleton和prototype是硬编码到代码中的,而request、session和global session,包括自定义scope类型,则属于可扩展的scope行列,它们都实现了Scope接口
public interface Scope{
Object get(String name,ObjectFactory objectFactory);
Object remove(String name);
void registerDestructionCallback(String name,Runnable callback);
String getConversationId();
}
要实现自己的Scope类型,首先需要给出一个Scope接口的实现类,接口定义中的4个方法并非都是必须的,但get和remove方法必须实现。
我们如果使用BeanFactory类型(当然,更应该实现configurableBeanFactory),我们可以通过如下的方式来注册Scope
Scope threadScope = new ThreadScope();
beanFactory.registerScope(“thread”,threadScope);
之后我们就可以 通过thread 名称指定bean 定义的scope为以上注册的threadscope了
除了直接编码调用ConfigurableBeanFactory的registerScope来注册scope,Spring还提供了一个专门用于统一注册自定义scope的BeanFactoryProcessor实现。