Spring 学习整理 -03- 对 Spring 中 Bean 的5种 Scope 作用域的理解

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。觉得此文有用的,不嫌麻烦的,就留个言呐,或者点个赞呐,要是嫌麻烦呢,也麻烦点个赞嘛 https://blog.csdn.net/qq_40147863/article/details/87861126

Spring 学习整理 -03- 对 Spring 中 Bean 的5种 Scope 的理解

为面试做准备,如果有文章内容有不对的地方,欢迎指出
参考原文:https://www.cnblogs.com/mxyhws/p/3716415.html

关于 Scope 作用域的理解

Scope 用来声明容器中的对象所应该处的限定场景或者说该对象的存活时间,即容器在对象进入其相应的 Scope 之前,生成并装配这些对象,在该对象不再处于这些 scope 的限定之后,容器通常会销毁这些对象。

一句话说 Scope 是定义 Spring 如何创建 bean 的实例的。

Spring 中 Scope 作用域有哪五种?

Spring 容器最初提供了两种 bean 的 scope 类型:singletonprototype,但发布2.0之后,又引入了另外三种 scope 类型,即 requestsessionglobal session 类型。不过这三种类型有所限制,只能在 Web 应用中使用。

也就是说,只有在支持 Web 应用的 ApplicationContext 中使用这三个 scope 才是合理的。

Scope 作用域的使用

在创建 bean 的时候可以带上 scope 属性,scope 有下面几种类型:

(1)singleton 作用域

当一个 bean 的作用域设置为 singleton,那么 Spring IOC 容器中只会存在一个共享的 bean 实例,并且所有对 bean 的请求,只要 id 与该 bean 定义相匹配,则只会返回 bean 的同一实例。换言之,当把一个 bean 定义设置为 singleton 作用域时,Spring IOC 容器只会创建该 bean 定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该 bean 的后续请求和引用都将返回被缓存的对象实例。

这里要注意的是 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 作用域

prototype 作用域部署的 bean,每一次请求(将其注入到另一个 bean 中,或者以程序的方式调用容器的 getBean()方法)都会产生一个新的 bean 实例,相当与一个 new 的操作,对于 prototype 作用域的 bean,有一点非常重要,那就是 Spring 不能对一个 prototype bean 的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个 prototype 实例后,将它交给客户端,随后就对该 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 作用域

request 表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前HTTP request 内有效,

配置实例:

request、session、global session 使用的时候首先要在初始化 web 的 web.xml 中做如下配置:
如果你使用的是 Servlet 2.4 及以上的 web 容器,那么你仅需要在 web 应用的 XML 声明文件 web.xml 中增加下述 ContextListener 即可:

web.xml 文件代码:

<web-app>
   ...
  <listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
  </listener>
   ...
</web-app>

如果是 Servlet 2.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 的作用域了:

(4)session 作用域

session 作用域表示该针对每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效

配置实例:
和 request 配置实例的前提一样,配置好 web 启动文件就可以如下配置:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/>

(5)global session 作用域

global session 作用域类似于标准的 HTTP Session 作用域,不过它仅仅在基于 portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享。在 global session 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围内。如果你在 web 中使用 global session 作用域来标识 bean,那么 web 会自动当成 session 类型来使用

配置实例:

和 request 配置实例的前提一样,配置好web启动文件就可以如下配置:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="global session"/>

更多文章链接

猜你喜欢

转载自blog.csdn.net/qq_40147863/article/details/87861126