【spring容器bean的作用域+spring容器是否是单例的一些问题】
Spring容器中Bean的作用域
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下5种作用域:
- singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
- prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
- request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
- session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
- globalsession:每个全局的HTTP Session,使用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的基本行为,通过scope属性指定,该属性可以接受singleton、prototype、request、session、globlesession5个值,分别代表以上5种作用域。下面的配置片段中,singleton和prototype各有一个:
|
1
2
3
4
|
<!-- 默认的作用域:singleton --><bean id="p1" class="com.abc.Person" /> <!-- 指定的作用域:prototype --><bean id="p2" class="com.abc.Person" scope="prototype" /> |
下面是一个测试类:
|
1
2
3
4
5
6
7
8
9
|
public class BeanTest { public static void main(String args[]) { //加载类路径下的beans.xml文件以初始化Spring容器 ApplicationContext context = new ClassPathXmlApplicationContext(); //分两次分别取同一个Bean,比较二者是否是同一个对象 System.out.println(context.getBean("p1") == context.getBean("p1")); System.out.println(context.getBean("p2") == context.getBean("p2")); }} |
执行结果分别是:true和false
从结果可以看出,正如上文所述:对于singleton作用域的Bean,每次请求该id的Bean,都将返回同一个实例,而prototype作用域的Bean, 每次请求都将产生全新的实例。
注意:早期指定Bean的作用域也可通过singleton属性指定,该属性只接受两个属性值:true和false,分别代表singleton和prototype的作用域。使用singleton属性则无法指定其他三个作用域。实际上Spring2.X不推荐使用singleton属性指定Bean的作用域,singleton属性是Spring 1.2.X的使用方式。
对于request作用域,查看如下Bean定义:
|
1
|
<bean id="loginAction" class="com.abc.LoginAction" scope="request" /> |
针对每次HTTP请求,Spring容器会根据loginActionBean定义创建一个全新的LoginAction实例,且该loginAction实例尽在当前HTTP Request内有效。因此,如果程序需要,完全可以自由更改Bean实例的内部状态;其他请求所获得的loginAction实例无法感觉到这种内部状态的改变。当处理请求结束时,request作用域的Bean将会被销毁。
注意:request、session作用域的Bean只对Web应用才真正有效。实际上通常只会将Web应用的控制器Bean才指定成request作用域
session作用域与request作用域完全类似,区别在于:request作用域的Bean对于每次HTTP请求有效,而session作用域的Bean对于每次Session有效。在Web应用中,为了让request和session作用域生效,必须将HTTP请求对象绑定到为该请求提供服务的线程上,这使得具有request和session作用域的Bean实例能够在后面的调用链中被访问到。
为此我们有两种配置方式:采用Listener配置或者采用Filter配置。当使用Servlet 2.4及以上规范的Web容器时,我们可以在Web应用的web.xml文件中增加Listener配置,该Listener负责为request作用域生效:
|
1
2
3
4
5
|
<listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class></listener> |
如果使用了只支持Servlet 2.4以前规范的Web容器,则该容器不支持Listener规范,故无法使用这种配置方式,只能改为使用Filter配置方式,配置片段如下:
|
1
2
3
4
5
6
7
8
9
10
|
<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作用域了。下面是Spring配置文件的片段:
|
1
|
<bean id="p3" class="com.abc.Person" scope="request" /> |
这样,Spring容器会每次HTTP请求都生成一个Person实例,当该请求响应结束时,该实例也随之消失。
如果Web应用直接使用Spring MVC作为MVC框架,即使用SpringDispatcherServlet或DispatcherPortlet来连接所有用户请求,则无需这些额外的配置,因为他们已经处理了所有和请求有关的状态处理。
注意:Spring 3.0 不仅可以为Bean指定已经存在的5个作用域,还支持自定义作用域,关于自定义作用域的内容,请参看Spring官方文档等资料。
【spring容器bean的作用域+spring容器是否是单例的一些问题】的更多相关文章
- spring容器bean的作用域 & spring容器是否是单例的一些问题
Spring容器中Bean的作用域 当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域.Spring支持如下5种作用域: singleto ...
- Spring中bean的作用域与生命周期
在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean.简单地讲,bean 就是由 IOC 容器初始化.装配及管理的对象,除此之外,bean 就与 ...
- spring中bean的作用域属性singleton与prototype的区别
1.singleton 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会 ...
- 浅析Spring中bean的作用域
一.前言 刚刚花了点时间,阅读了一下Spring官方文档中,关于bean的作用域这一块的内容.Spring-4.3.21官方文档中,共介绍了七种bean作用域,这篇博客就来简单介绍一下这七种作用域 ...
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
- Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean
Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...
- Spring源码分析(十五)获取单例
本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例be ...
- Spring中Bean的作用域、生命周期
Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...
- Spring中Bean的作用域
1.在Spring的早期版本中,仅有两个作用域:singleton和prototype,前者表示Bean以单例的方式存在:后者表示每次从容器中调用Bean时,都会返回一个新的实例 2.Spring 2 ...
随机推荐
- java入门了解09
1.JDK5新功能 (一).静态导入 import static java.lang.System.out; 使用时:直接写调用out()方法 (二).增强的for循环 只能用在数组:或是实现了Ite ...
- Spark- Checkpoint原理剖析
Checkpoint,是Spark 提供的一个比较高级的功能.有的时候,比如说,我们的 Spark 应用程序,特别的复杂,然后从初始的RDD开始,到最后拯个应用程序完成,有非常多的步骤,比如超过20个 ...
- Spring MVC工作原理(好用版)
Spring MVC工作原理 参考: SpringMVC工作原理 - 平凡希 - 博客园https://www.cnblogs.com/xiaoxi/p/6164383.html SpringMVC的 ...
- orcal操作锦集
更新时间:update qs_settle_dt_cfg set end_date=to_date('9999-12-31','yyyy-MM-dd');查询时间:select to_char( e ...
- 列存储压缩技巧,除公共除数或者同时减去最小数,字符串压缩的话,直接去重后用数字ID压缩
Column-store compression At a high level, doc values are essentially a serialized column-store. As w ...
- SSH三大框架的搭建整合(struts2+spring+hibernate)(转)
原文地址:http://blog.csdn.net/kyle0349/article/details/51751913 尊重原创,请访问原文地址 SSH说的上是javaweb经典框架,不能说100% ...
- Python-unittest参数化
做接口测试的时候,同一个接口,输入的参数一样,参数值不一样,这时候,写多个case就是冗余的,就可以用参数化来实现,第三方模块有这个实现参数化的功能,安装pip install nose-param ...
- Oracle--存储过程和自定义函数
一.相关概念 1.存储过程和存储函数 ~指存储在数据库中供所有用户程序调用的子程序 ~存储过程和存储函数的相同点:完成特定功能的程序 ~存储过程和存储函数区别:是否用return语句返回值 2.创建和 ...
- 将tomcat7解压版注册为windows系统服务
一.修改service.bat文件(...tomcat7\bin\service.bat) 该文件中共修改两处即可 ①:在文件的开头加入以下设置,分别是java的安装路径.Tomcat的安装路径及服务 ...
- fedora使用mac osx字体和渲染方式
fedora 19的倒退(中文显示有问题)让人感到很沮丧,不过,后来还是找到了一个很好的解决方案:使用max osx的字体和渲染方式 1. 安装infinality字体渲染软件: rpm -Uvh h ...