Bean的作用域
在Spring中,那些组成应用程序的主体及由Spring IOC容器所管理的对象,被称之为bean。简单地讲,bean就是由IOC容器初始化、装配及管理的对象。而这些对象,都有它对应的作用域。
几种作用域中,request、session作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于web的Spring ApplicationContext环境。
1、Singleton
当一个bean的作用域为Singleton,那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
Singleton是单例类型,就是在创建容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。
【注意】Singleton作用域是Spring中的缺省作用域。在我们不声明的情况下,默认就是Singleton
我们也可以在xml中显示设置它
<bean id="user" class="com.jh.domain.User" scope="singleton"/>
Singleton的作用范围:
2、Prototype
当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
Prototype是原型类型,它在我们创建容器的时候没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
在XMl中可以这样设置,将bean定位为prototype
<bean id="user" class="com.jh.domain.User" scope="prototype" />
prototype的作用范围:
3、Request
当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;
即每一个HTTP请求,都会单独创建一个bean
,若请求结束,bean
也会随之销毁。
使用request
作用域一般不会存在线程安全问题,因为在Web
应用中,每个请求都是由一个单独的线程进行处理,所有线程之间并不会共享bean
,从而不会存在线程安全的问题。
如果使用的是注解扫描配置bean
,那么在bean
所属的类上使用@RequestScope
注解即可使用此作用域,若是基于xml
文件,则通过bean
的scope
配置项:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
4、Session
Session
作用域将bean的使用范围一次在一次http会话
中,对于每一个会话,Spring容器都会创建一个单独的bean
,若Session被销毁,则bean也随之销毁。
针对某个HTTP Session
,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。
与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。
session
作用域只能使用在Web
应用中。我们可以使用@SessionScope
将bean指定为session
作用域,也可以使用xml配置方式:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
5、Application
Spring 容器通过为整个 Web 应用程序使用一次 bean 定义来创建 bean 的新实例。也就是说,bean 在级别上进行范围范围存储,并存储为常规属性。
这与 Spring Singleton Bean
有些类似,但在两个重要方面有所不同:它是每个的单元,而不是每个 Spring"应用程序上下文"(对于它,在任何给定的 Web 应用程序中可能有多个),它实际上是公开的,因此作为属性可见。
application
作用域也只能用于web
应用中。使用方式和之前几种类似,可以通过@ApplicationScope
注解,也可以使用xml
配置文件:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
6、websocket
websocket
是一种应用层的通信协议,它提供应用层的全双工通信,而Spring提供对websocket
协议的支持,于是就有了这么一个作用域。在Spring官方文档中,并没有对这个作用域进行详细描述,但是我们也可以通过名称推断出来。
若一个bean的作用域为websocket
,则只作用于一次websocket
通信。若连接被释放,则bean也会被销毁。