概念:由Spring容器创建的Bean的生存期被称为Bean的作用域。
Bean中,使用<bean>元素的scope特性来指定一个Bean定义的作用域。
<bean id=”a” class=”com.lz.A” scope=”singleton” />
Bean定义了5种作用域,分别为singleton(单例)、prototype(原型)、request、session和global session,其中request和session作用域只能在web应用程序中。如果在一个独立的应用程序中使用他们,将导致Spring无法启动。
Singleton(单例)
默认情况下,由Spring容器创建的所有Bean都是Singleton作用域,也就是说,针对一个Bean定义只创建了一个Bean实例,并且Spring容器可以在整个应用程序生存期中使用该实例(Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象)。
当不同的Bean与不同的层(控制层、服务层和数据访问对象层)相对应时,可以使用Singleton作用域。此时创建的实例都是无状态实例,在同一时间服务于不同的请求。
prototype(原型)
prototype作用域类似于在Java代码中使用new操作符创建对象。每当需要在容器中或者通过Bean引用从其他Bean定义中,又或者通过显式Bean查找(使用ApplicationContext.getBean()方法)从应用程序代码中访问prototype作用域Bean时就会创建他们。
Request
每当一个新的web请求(Http请求)到达应用程序时就会创建一个Request作用域Bean,并且在整个请求过程中使用相同的Bean实例。而对不同的web请求(Http请求)则会产生新的Bean,而且该Bean仅在当前Http Request内有效,而其它请求无法看到当前请求中状态的变化,当当前web请求(Http请求)结束,该Bean实例也将会被销毁。
Session
在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效。
同Http请求相同,每一次session请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的session请求内有效,请求结束,则实例将被销毁。
注意:当定义Request作用域Bean和Session作用域Bean时,必须在<bean>元素中放置<aop:scoped-proxy/>元素作为一个子元素。该指令可以让Spring容器在运行时动态生成一个扩展自Bean定义类的类,以及创建一个使用该动态生成类的代理对象。
global Session
在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。
总结:
作用域名称 |
作用域定义 |
singleton |
从Bean定义中近创建一个实例。这是默认的作用域 |
prototype |
每一次对Bean定义的访问(无论是通过其他Bean定义还是通过getBean()方法)都会创建一个新的Bean实例。类似于Java中的new操作符 |
request |
在整个web请求过程中使用相同的Bean实例。每一个web请求都会创建一个新的Bean实例。仅适用支持web的ApplicationContexts |
session |
针对一个特定的HTTP会话使用相同的Bean实例。不同的HTTP会话创建新的Bean实例。仅适用支持web的ApplicationContexts |
globalSession |
类似于前面介绍的标准HTTP Session作用域(如前所述),仅适用于基于portlet的web应用程序的上下文 |