摘自《Spring 解密》java
scope用来声明IOC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在 对象进入相应的scope以前,生成并装配这些对象,在该对象再也不处于这些scope的限定以后,容器一般会销毁这些对象。打个比方吧!咱们都是处在社会 (容器)中,若是把中学教师做为一个类定义,那么当容器初始化这些类以后,中学教师只能局限在中学这个场景中,中学,就能够看作中学教师的scope。web
Spring容器最初提供了两种bean的scope类型:singleton和 prototype,但发布2.0以后,又引入了另外三种scope类型,即request,session和global session类型。不过这三种类型有所限制,只能在web应用中使用,也就是说,只有在支持web应用的ApplicationContext中使用这 三个scope才是合理的。spring
可使用bean的singleton或scope属性来指定相应对象的scope,其中,scope属性只能在XSD格式的文档生命中使用,相似于以下代码所演示的形式:设计模式
DTD:session
<bean id ="mockObject1" class="..." singleton="false" />spa
XSD:prototype
<bean id ="mockObject1" class="..." scope="prototype" />设计
注意:这里的singleton和设计模式里面的单例模式不同,标记为singleton的bean是由容器来保证这种类型的bean在同一个容器内只存在一个共享实例,而单例模式则是保证在同一个Classloader中只存在一个这种类型的实例。对象
1. singleton生命周期
singleton类型的bean定义,在一个容器中只存在一个实例,全部对该类型bean的依赖都引用这一单一实例,这就好像每一个幼儿园都会有一个滑梯同样,这个幼儿园的小朋友共同使用这一个滑梯,而对于幼儿园容器来讲,滑梯就是一个singleton的bean。
此外,singleton类型的bean定义,从容器启动,到他第一次被请求而实例化开始,只要容器不销毁或退出,该类型的bean的单一实例就会一直存活。
一般状况下,若是你不指定bean的scope,singleton即是容器默认的scope,因此,下面三种配置,形式实际上达成的是一样的效果:
DTD or XSD:
<bean id ="mockObject1" class="..." />
DTD:
<bean id ="mockObject1" class="..." singleton="true" />
XSD:
<bean id ="mockObject1" class="..." scope="singleton" />
2 prototype
scope为prototype的bean,容器在接受到该类型的对象的请求的时候,会每次都从新 生成一个新的对象给请求方,虽然这种类型的对象的实例化以及属性设置等工做都是由容器负责的,可是只要准备完毕,而且对象实例返回给请求方以后,容器就不 在拥有当前对象的引用,请求方须要本身负责当前对象后继生命周期的管理工做,包括该对象的销毁。也就是说,容器每次返回请求方该对象的一个新的实例以后, 就由这个对象“自生自灭”了。
让咱们继续幼儿园的比喻,咱们今天要分苹果了!将苹果的bean的scope属性声明为 prototype,在每一个小朋友领取苹果的时候,咱们都是发一个新的苹果给他,发完以后,小朋友爱怎么吃就怎么吃,爱何时吃何时吃,可是注意吃 完要把果核扔到垃圾箱哦!对于那些不能共享使用的对象类型,应该将其定义的scope设为prototype,一般,声明为prototype的的 bean,都是一些有状态的,好比保存为每一个顾客信息的对象。
能够用一下方式定义prototype类型的bean:
DTD:
<bean id ="mockObject1" class="..." singleton="false" />
XSD:
<bean id ="mockObject1" class="..." scope="prototype" />
3 request ,session和global session
这三个类型是spring2.0以后新增的,他们不像singleton和prototype那么通用,由于他们只适用于web程序,一般是和XmlWebApplicationContext共同使用,将在第6章详细讨论,这里简单介绍。
request:
<bean id ="requestPrecessor" class="...RequestPrecessor" scope="request" />
Spring容器,即XmlWebApplicationContext 会为每一个HTTP请求建立一个全新的RequestPrecessor对象,当请求结束后,,该对象的生命周期即告结束。当同时有10个HTTP请求进来 的时候,容器会分别针对这10个请求建立10个全新的RequestPrecessor实例,且他们相互之间互不干扰,从不是很严格的意义上 说,request能够看作prototype的一种特例,除了场景更加具体以外,语意上差很少。
session:
对于web应用来讲,放到session中最广泛的就是用户的登陆信息,对于这种放到session中的信息,咱们咱们可使用以下形式的制定scope为session:
<bean id ="userPreferences" class="...UserPreferences" scope="session" />
Spring容器会为每一个独立的session建立属于本身的全新的UserPreferences实例,他比request scope的bean会存活更长的时间,其余的方面真是没什么区别。
global session:
<bean id ="userPreferences" class="...UserPreferences" scope="globalsession" />
global session只有应用在基于porlet的web应用程序中才有意义,他映射到porlet的global范围的session,若是普通的servlet的web 应用中使用了这个scope,容器会把它做为普通的session的scope对待。
(我只是据说过porlet这个词,好像是和servlet相似的一种java web技术,你们之后遇到的时候能够搜一下!)
spring还支持一种自定义scope类型,我就很少写了,有点累了。。。之后还会写更多的笔记,你们敬请期待~