上篇文章较为详细了对各种情况下bean依赖的配置做了说明,但一直没有对Scope这个属性进行说明。本篇将一起学习。本文演示代码下载地址
当我们在xml配置文件中配置一个bean的定义的时候,可以认为是配置了一个模板,可以根据这个模板来生成很多个对象来满足整个应用程序的依赖关系,同时我们也可以配置对象的Scope。
Scope可以理解为SpringIOC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在对象进入相应的scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象。
截止到目前为止,spring提供了六种类型的scope:
1. singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
2. prototype 表示每次获得bean都会生成一个新的对象
3. request 表示在一次http请求内有效(只适用于web应用)
4. session 表示在一个用户会话内有效(只适用于web应用)
5. global Session 与上面类似,但是用于移动设备中的服务器中。
6. globalSession 表示在全局会话内有效(只适用于web应用)
一般情况下,前两种的scope就已经足够满足需求,后几种运用于web容器中,默认的scope是singleton。
注:spring3.0开始提供 SimpleThreadScope
,但是默认没有注册。
单例
基本
Singleton 是spring容器默认采用的scope。注意这里的Singleton和设计模式中所描述的概念不同。设计模式中指每个classLoader一个类只有一个实例,而这里指每个Spring容器对于一个 beandefinition只有一个实例。
见下图说明:
下节中的代码集中说明Singleton和prototype 。
懒加载
默认情况下,Singleton的bean是在spring容器初始化的过程中进行初始化的,这样做的好处是可以尽早的发现配置的错误。
但是如果有需要的话,可以取消这个机制,使用bean标签的lazy-init 属性 ,如下:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
也可以在配置文件根标签beans 使用以下配置,取消预加载的行为:
<beans default-lazy-init="true">
<!-- no beans will be pre-instantiated... -->
</beans>
原型
Scope为prototype 的bean定义,每一次需要的时候总是重新创建一个全新的对象,不论是依赖注入的需要,还是调用applicationContext的getBean方法。如下图说明:
与其他类型的scope相比,spring不完全管理scope为prototype的生命周期,spring容器仅仅是实例化、配置和组装一个实例给客户,而没有进一步记录它的状态。Spring容器会执行所有bean的初始化方法,但是对于scope为prototype的bean来说,其destruction生命周期函数不会被执行,所以其持有的昂贵的资源需要客户端自己释放。
下面的代码进一步理解,首先是Client1和client2 两个类,他们完全一样,而AccoutDao是一个空类,什么也没有:
package com.test.scope.si;
/**
* @Description:有三个 AccoutDao 的引用,他们的scope依次为默认、单例(singleton)、原型( prototype)
* 省略的get set方法
*/
public class