Spring Bean 的五个作用域

一、五个作用域(scope)

作用域限定了 Bean 的作用范围。在 Spring 配置文件定义 Bean 时,通过声明 scope 配置项,可以灵活定义 Bean 的作用范围。例如:
希望 IOC 容器每次返回的 Bean 是同一个实例时,可以设置 scope 为 singleton;
希望 IOC 容器每次返回的 Bean 实例是一个新的实例时,可以设置 scope 为 prototype。

scope 配置项有 5 个属性,用于描述不同的作用域:singleton、prototype、request、session、global-session。说明如下:

  1. singleton:唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  2. prototype:每次请求都会创建一个新的 bean 实例。
  3. request:每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
  4. session:每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
  5. request、session 和 global session 类型只适用于 web 程序,通常是和 XmlWebApplicationContext 共同使用。

二、singleton(单例)

  1. 默认情况,Spring 在读取 xml 文件的时候,就会创建对象。
  2. 在创建对象的时候(先调用构造器),会去调用init-method=".."属性值中所指定的方法。
  3. 对象在被销毁的时候,会调用destroy-method="..."属性值中所指定的方法(例如调用 container.destroy() 的时候)。
  4. lazy-init="true",可以让该对象在第一次被访问的时候创建,而不是被加载的时候。

此外,singleton 类型的 bean 定义从容器启动到第一次被请求而实例化开始,只要容器不销毁或退出,该类型的 bean 的单一实例就会一直存活。典型单例模式,如同 servlet 在 web 容器中的生命周期。

三、prototype(原型)

  1. Spring 读取 xml 文件的时候,不会创建对象。
  2. 在每一次访问该对象的时候,Spring 容器都会创建这个对象,并且调用init-method=".."属性值中所指定的方法。
  3. 对象销毁的时候,Spring 容器不会调用任何方法。因为不是单例,该类型的对象有很多个,Spring 容器一旦把这个对象交给请求方之后,就不再管理这个对象了。

理解:

如同分苹果,将苹果的 bean 的 scope 属性声明为 prototype。在每个人领取苹果的时候,都是发一个新的苹果给他,发完之后,别人爱怎么吃就怎么吃,爱什么时候吃什么时候吃,但是注意吃完要把苹果核扔到垃圾箱!对于那些不能共享使用的对象类型,应该将其定义的 scope 设为 prototype。

最典型的体现就是 Spring 与 struts2 进行整合时,要把 action 的 scope 改为 prototype。
因为 Spring 默认 scope 是单例模式,这样只会创建一个 Action 对象,每次访问都是同一个Action对象,数据不安全。struts2 是要求每次访问都对应不同的 Action,scope=“prototype” 可以保证当有请求的时候都创建一个 Action 对象。

四、request

<bean id ="requestPrecessor"  
	class="...RequestPrecessor" scope="request" />

Spring 容器,即 XmlWebApplicationContext 会为每个HTTP请求创建一个全新的 RequestPrecessor 对象。当请求结束后,该对象的生命周期即告结束,如同 java web 中 request 的生命周期。当同时有 10 个 HTTP 请求进来的时候,容器会分别针对这 10 个请求创建 10 个全新的 RequestPrecessor 实例,且它们之间互不干扰。简言之,request 可以看做 prototype 的一种特例,除了场景更加具体之外,语意上差不多。

五、session

对于 web 应用来说,放到 session 中最普遍的就是用户的登录信息。对于这种放到 session 中的信息,可以使用如下形式的制定 scope 为 session:

<bean id ="userPreferences"  
	class="...UserPreferences" scope="session" />

Spring 容器会为每个独立的 session 创建属于自己的全新的 UserPreferences 实例,比 request、scope 的 bean 会存活更长的时间,其他的方面没区别,如同 java web 中 session 的生命周期

六、global session

<bean id ="userPreferences" 
	class="...UserPreferences" scope="globalsession" />

global session 只有应用在基于 porlet 的 web 应用程序中才有意义,它映射到 porlet 的 global 范围的 session,如果普通的 servlet 的 web 应用中使用了这个 scope,容器会把它作为普通的 session 的 scope 对待。

七、scope 配置

1️⃣xml 方式:进行 bean 的配置时,指定 scopexml配置bean

2️⃣注解方式:前提为配置 Spring 为注解配置Spring Bean 的五个作用域_第1张图片

你可能感兴趣的:(Spring,java)