上篇文章较为详细了对各种情况下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 Client1 {private AccoutDao accoutDao;private AccoutDao accoutDaob;private AccoutDao accoutDaoc;@Overridepublic String toString() {return "Client1 [accoutDao=" + accoutDao + ", accoutDaob=" + accoutDaob + ", accoutDaoc=" + accoutDaoc + "]";}}
下面是配置文件:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns=""xmlns:xsi=""xsi:schemaLocation=""><!– 定义三个 AccoutDao bean 依次为默认配置 单例原型 –><bean id="account1" class="com.test.scope.si.AccoutDao"></bean><bean id="account2" class="com.test.scope.si.AccoutDao" scope="singleton"></bean><bean id="account3" class="com.test.scope.si.AccoutDao" scope="prototype"></bean><!– 定义 Client1 bean 和 Client2 bean 他们的定义完全一样,这里只是为了说明singleton 和 prototype 区别他们都有三个依赖,分别是以上定义的bean–><bean id ="c1a" class="com.test.scope.si.Client1"><property name="accoutDao" ref="account1"></property><property name="accoutDaob" ref="account2"></property><property name="accoutDaoc" ref="account3"></property></bean><bean id ="c2a" class="com.test.scope.si.Client2"><property name="accoutDao" ref="account1"></property><property name="accoutDaob" ref="account2"></property><property name="accoutDaoc" ref="account3"></property></bean></beans>
下面是测试程序:
接着我们去了遇龙河,那里的水清澈见底,我把脚伸进水里,