7.5.2:容器中Bean的作用域

当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定作用域。Spring支持如下5种作用域:

Spring支持的作用域
作用域说明
singleton单例模式,在整个Spring IOC容器中,使用singleton定义的Bean将只有一个实例。
prototype原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
request对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的
Bean实例。只有在Web应用中使用Spring时,该作用域才真正有效。
session对于每次HTTP Session,使用session定义的Bean都将产生一个新实例,即每次HTTP Session都将产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才真正有效。
global session每个全局的HTTP Session对应一个Bean实例。典型的情况下,仅在使用portlet context的时候有效。
只有在Web应用中使用Spring时,该作用域才真正有效。
比较常用的是singleton和prototype两种作用域。对于 singleton 作用域的Bean,每次请求该Bean都将获得相同的实例,容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成 prototype 作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new关键字创建Bean实例,一旦创建成功,容器不再跟踪实例,也不会维护Bean实例的状态。

如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此除非必要,否则尽量避免将Bean设置成prototype作用域。

<bean id="p1" class="com.Person"/>
<bean id="p2" class="com.Person" scope="prototype"/>
public class Test {

	public static void main(String[] args) {
		
		ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
		System.out.println(ctx.getBean("p1")==ctx.getBean("p1"));//true
		System.out.println(ctx.getBean("p2")==ctx.getBean("p2"));//false
	}

}

对于 request 作用域,查看如下Bean定义:

<bean id="loginAction" class="org.struts2.LoginAction" scope="request"/>
针对每次HTTP请求,Spring容器会根据loginAction Bean定义创建一个全新的LoginAction Bean实例,且该loginAction Bean实例仅在当前HTTP Request内有效。因此如果程序需要,完全可以自由更改Bean实例的内部状态;其他请求所获得的loginAction Bean实例无法感觉到这种内部状态的改变。当处理请求结束时,request作用域的Bean实例将被销毁。

session 作用域与request作用域完全类似,区别在于:request作用域的Bean对于每次HTTP请求有效,而session作用域的Bean则对于每次HTTP Session有效。

request和session作用域只在Web应用中才有效,并且必须在Web应用中增加额外配置才会生效。有两种方式:采用Listener配置或采用Filter配置。

① Listener配置:

当使用支持Servlet2.4及以上规范的Web容器时,我们可以在Web应用的web.xml文件中增加如下Listener配置,该Listener配置负责为request作用域生效。

<web-app>
   ...
<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
 </listener>
   ...
</web-app>
如果使用了只支持Servlet2.4以前规范的Web容器,则该容器不支持Listener规范,故无法使用这种配置方式,只能改为使用Filter配置方式。

② Filter配置:

<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.xml文件中增加了如上任意一种配置,程序就可以在Spring配置文件中使用request或session作用域了。

如果Web应用直接使用Spring MVC作为MVC框架,即用SpringDispatcherServlet或DispatcherPortlet来拦截用户请求,则无须这些额外的配置,因为SpringDispatcherServlet或DispatcherPortlet已经处理了所有和请求有关的状态处理。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值