当通过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
publicclass BeanTest {
  publicstatic void main(String args[]) {
    //加载类路径下的beans.xml文件以初始化Spring容器
    ApplicationContext context = newClassPathXmlApplicationContext();
    //分两次分别取同一个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官方文档等资料。

原文出处: 摆渡者

from: http://www.importnew.com/20736.html

Spring容器中Bean的作用域相关推荐

  1. 工具类:获取 spring 容器中 bean

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. package com.orange.utils;import org.springframewor ...

  2. IoC基础篇(一)--- Spring容器中Bean的生命周期

    IoC基础篇(一)--- Spring容器中Bean的生命周期 日出日落,春去秋来,花随流水,北雁南飞,世间万物皆有生死轮回.从调用XML中的Bean配置信息,到应用到具体实例中,再到销毁,Bean也 ...

  3. spring 容器中bean的扩展点记录 —— 个人学习记录

    在spring容器创建bean的生命周期中,存在很多个可以让我们扩展的口子 1.拿到beanFactory使用beanDefinition创建bean之前,通过实现BeanFactoryPostPro ...

  4. 理解Spring框架中Bean的作用域

    本篇介绍Spring Bean实例的作用范围,Spring Bean实例的作用范围由配置项scope限定.通过本篇的学习,可以达成如下目标. ● 应用scope配置项配置Bean的作用域 ● 应用单例 ...

  5. Spring容器中的Bean是否会被GC呢?

    Spring容器中的Bean是否会被GC呢?最近好几次被校招实习生问及,对于初学者来说,这应该是一个有意思的问题,鉴于此,笔者顺便写个这个文档. 1.Spring容器中Bean的作用域 当通过Spri ...

  6. 学习Spring(六) -- Spring中Bean的作用域以及生命周期

    2019独角兽企业重金招聘Python工程师标准>>> Bean的作用域 默认情况下,bean的作用域为单例模式(singleton): 在applicationContext创建时 ...

  7. Spring注解驱动开发第11讲——面试官让我说说:如何使用FactoryBean向Spring容器中注册bean?

    写在前面 经过前面的学习,我们知道可以通过多种方式向Spring容器中注册bean.可以使用@Configuration注解结合@Bean注解向Spring容器中注册bean:可以按照条件向Sprin ...

  8. 将Bean放入Spring容器中的五种方式

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/weixin_43741092/ article/details/120176466 将bean放 ...

  9. SpringBoot 之 普通类获取Spring容器中的bean

    SpringBoot 之 普通类获取Spring容器中的bean 转载于:https://www.cnblogs.com/lwmp/p/8892927.html

最新文章

  1. Linux命令行之逗趣无极限
  2. python2与python3在absolute import的区别
  3. 设计模式在实际业务应用中的介绍之2——业务工厂
  4. LintCode刷题笔记-- BackpackIII
  5. Dubbo 2.7.7 发布,FastJson 升级了!
  6. 新手怎么入门电子电路设计?
  7. html页面怎么记住密码,使用html的localstorage实现登录页面的记住密码功能
  8. 微信小程序游戏开发│石头剪刀布游戏(附源码)
  9. 1024:程序员,你的身体还好吗?
  10. 张朝阳夜跑33公里:直播聊物理 揭示“超级月亮”成因
  11. 最强nba体验服显示服务器正在停机,最强NBA体验服
  12. adb:failed to install app.apk Failure [INSTALL_FAILED_VERSION_DOWNGRADE: Package Verification Result
  13. 基于区块链技术的智慧供应链创新应用
  14. SDWebImage 图片加载失败
  15. Java项目:药店信息管理系统(java+SSM+JSP+layui+maven+mysql)——计算机毕业设计
  16. html asterisk 电话,WebGuide: Aplicació Web (HTML5) i Asterisk utilitzant VoIP
  17. 调侃计算机专业的句子,调侃生活的幽默句子
  18. (二)库存计划-经济订货量(EOQ)
  19. ue4-runtime_ubuntu_docker_使用教程方法
  20. linux文件操作函数

热门文章

  1. 转载--tomcat整合apr
  2. 宜信创始人唐宁:技术到处都是,关键看怎么用
  3. 回填用土好还是砂石料好_卫生间做回填好还是做架空好?这两者有哪些优缺点...
  4. 转载:谢谢原作者:块设备驱动实战基础篇四 (逐渐成型,加入ioctl通信机制)
  5. Chromium:安装depot_tools及获取Chromium源代码
  6. 计网 - 一台内存在 8G 左右的服务器,可以同时维护多少个连接?
  7. 并发编程-05线程安全性之原子性【锁之synchronized】
  8. Spring MVC-07循序渐进之验证器 下 (JSR 303验证)
  9. 监控服务器项目报备,智慧环保监控预警平台运维项目
  10. nginx在linux reload报错,linux下安装nginx