Spring bean 的5个作用域
Spring Bean的默认作用域为:singleton。它相比其他作用域的优点是系统开销小,Bean实例一旦创建成功便可重复使用。
1.singleton作用域:
Spring IOC容器中只会创建该bean定义的唯一的共享的bean实例,被存储到单例缓存(singleton cache)中,对针对该bean的后续请求和引用,只要id与该bean定义相匹配,都将返回被缓存的对象实例。单例的模式由bean factory自身来维护。
这里注意:singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。
配置实例:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/>
或者
<bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>
2.prototype作用域
原形范围与单例范围相反,为每一个bean请求提供一个实例。
每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当于一个new的操作。
注意,此时,Spring不能对一个 prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就不再管理该prototype实例,任何配置好的析构生命周期回调方法都将不会被调用,这与其他作用域的容器都会调用所有对象的初始化生命周期回调方法不。
清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)
配置实例:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/>
或者
<beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/>
3.Request
在请求bean范围内会每一个来自客户端的网络请求(HTTP请求)创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收(仅在当前HTTP request内有效)。
配置实例: request、session、global session使用的时候,首先要在初始化web的web.xml中做如下配置:
Servlet 2.4及以上的web容器:
在web应用的XML声明文件web.xml中增加下述ContextListener即可: <web-app>
...
<listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>
...
</web-app>
Servlet2.4以前的web容器:
需要使用一个javax.servlet.Filter的实现:
<web-app>
...
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name> <url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
接着既可以配置bean的作用域了:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="request"/>
4.Session
与请求范围类似,确保每个session(每一次HTTP请求)中有一个bean的实例,在session过期后,bean会随之失效(仅在当前HTTP session内有效)。
配置实例:
和request配置实例的前提一样,配置好web启动文件就可以如下配置:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/>
5.global session
global session作用域类似于标准的HTTP Session作用域,global-session和Portlet应用相关,仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么,web会自动当成session类型来使用。
一个例子,当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。
配置实例:
和request配置实例的前提一样,配置好web启动文件就可以如下配置:
<bean id="role" class="spring.chapter2.maryGame.Role" scope="global session"/>