Scope的概念
声明容器中的对象的生命周期。当对象在Spring容器中组装生成之后,由scope负责该对象在容器中的读取和销毁操作。
Scope的5种类型
Spring Framework支持五种作用域。 最初提供了两种类型: singleton和prototype。在2.0后引入了三种只能在web应用的ApplicationContext中使用的类型: request, session, global session。理论上,Spring 2.0支持无数多种类型bean,用户可根据自己的需要,增加新的bean类型。
默认是singleton。
Singleton
在Spring IOC容器中,只存在一个共享的bean实例。这个单一实例被存储在单例缓存(Singleton Cache)中,对于所有针对该bean的后续请求和引用,只要ID和定义相匹配,就返回同一实例。
区分:
单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton作用域表示一个容器中只存在一个bean。
Prototype
对该类对象的每一个请求,都会产生一个新的BEAN实例,相当于一个new操作。
特殊的一点是, Spring容器无法对prototype bean的整个生命周期负责,容器在初始化、配置、装配完一个prototype实例后,将它交给调用者,就不再管它了,任何配置好的析构生命周期回调方法都不会被调用。清除prototype对象并释放持有的资源,都由调用者负责。
对于其他作用域,容器会调用所有对象的初始化生命周期回调方法。
Request
针对每一次HTTP请求,都会产生一个新的BEAN,同时该BEAN仅在当前HTTP request内有效。
注意!!request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可。如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现,这里略。
Session
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效。
Global session
类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。
使用Tips
默认情况下,从bean工厂所取得的实例为Singleton。单态模式的bean由IOC容器管理,非线程安全。
有状态的bean都使用Prototype作用域,而对无状态的bean则应该使用singleton作用域。
如果你希望容器里的某个bean拥有其中某种新的web作用域,除了在bean级上配置相应的scope属性,还必须在容器级做一个额外的初始化配置。即在web应用的web.xml中增加一个ContextListener。
在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”。prototype为原型模式 , 每次action请求过来都会创建一个action。
对那些Dao的实现类推荐scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些。
参考文献
<Spring 解密>