在大多数情况下,单例bean是很理想的方案。初始化和垃圾回收对象实例所带来的的成本只留给一些小规模任务,在这些任务中,让对象保持无状态并且在应用中反复重用这些对象可能并不合理。在这种情况下,将class声明为单例的bean会被污染,稍后重用的时候会出现意想不到的问题。

Spring定义了多种作用域,可以基于这些作用域创建bean,包括:

  • 单例(singleton):在整个应用中,只创建bean的一个实例。
  • 原型(prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的实例。
  • 会话(session):在Web应用中,为每个会话创建一个bean实例。
  • 请求(request):在Web应用中,为每个请求创建一个bean实例。

单例是默认的作用域,如果选择其他作用域,要使用@Scope注解,它可以与@Component或@Bean一起使用:

1 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
2 import org.springframework.context.annotation.Scope;
3
4 @Component
5 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
6 public class Notepad{...}

当然也可以在@Bean下使用,参数可以直接写字符串prototype,singleton等,但并没有上述方式安全。

在xml模式中,可以在bean的属性中添加scope="prototype":

<bean id="notepad" class="..."  scope="prototype"/>

使用会话和请求作用域

使用会话作用域的bean最合适的莫过于购物车了,一个用户用一个购物车,而不是共用,或者因商品种类不同而创造无用的购物车。因为它与给定的用户关联性最大。示例如下:

 1 package soundSystem;
 2
 3 import org.springframework.context.annotation.Scope;
 4 import org.springframework.context.annotation.ScopedProxyMode;
 5 import org.springframework.stereotype.Component;
 6 import org.springframework.web.context.WebApplicationContext;
 7
 8 @Component
 9 @Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
10 public class JDShoppingCart implements ShoppingCart{
11     public ShoppingCart getJDShoppingCart(){
12         return new JDShoppingCart();
13     }
14 }

这里,我们将value设置成了WebApplicationContext中的SCOPE_SESSION常量(它的值是session)。表明为Web应用中的每个会话创建一个ShoppingCart。这会创建多个ShoppingCart实例,但对于给定的会话,只创建一个实例。也就是说,在当前会话相关的操作中,ShoppingCart是单例的。

要注意的是,还有一个代理模式的属性,它被设置成ScopedProxyMode.INTERFACES。这个属性解决了讲会话或请求作用域的bean注入到单例bean中所遇到的问题。在描述proxyMode属性之前,我们先来看看proxyMode所解决问题的场景。假如要将ShoppingCart bean注入到单例StoreService bean的Setter方法中:

 1 package soundSystem;
 2
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Component;
 5
 6 @Component
 7 public class StoreService {
 8 private ShoppingCart shoppingCart;
 9
10 @Autowired
11 public void setShoppingCart(ShoppingCart shoppingCart) {
12     this.shoppingCart = shoppingCart;
13 }
14 }

因为StoreService是一个单例的bean,会在Spring应用上下文加载的时候创建。当它创建的时候,Spring会试图将ShoppingCart bean注入到setter方法中,但是ShoppingCart bean是会话作用域的,此时并不存在,直到某个用户进入系统,创建了会话之后,才会出现ShoppingCart实例。

另外,系统中将会有多个ShoppingCart实例:每个用户一个。我们并不想让Spring注入某个固定的ShoppingCart实例到StoreService中。我们希望的是当StoreService处理购物车功能时,它所使用的ShoppingCart实例恰好是当前会话所对应的那个。

所以Spring并不会将实际的ShoppingCart bean注入到StoreService中,Spring会注入到一个ShoppingCart bean的代理,这个代理会暴露与ShoppingCart相同的方法,所以StoreService会认为它是一个购物车。但是当StoreService调用ShoppingCart的方法时,代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean。

现在,proxyMode被设置成ScopedProxyMode.INTERFACE常量,表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean。如果需要实现类,则设置为ScopedProxyMode.TARGET_CLASS即可。

xml模式下配置代理模式

1 <bean id="jDShoppingCart" class="soundSystem.JDShoppingCart" scope="session">
2     <aop:scoped-proxy/>
3 </bean>

也可以将proxy-target-class设置为false,从而要求它生成基于接口的代理:

1         <bean id="jDShoppingCart" class="soundSystem.JDShoppingCart" scope="session">
2             <aop:scoped-proxy proxy-target-class="false"/>
3         </bean>

转载于:https://www.cnblogs.com/yw0219/p/5990911.html

Spring-bean的作用域相关推荐

  1. spring bean的作用域和生命周期

    一.spring bean的作用域 五种作用域:singleton.prototype.request.session.globalSession request.session和global ses ...

  2. Spring Bean的作用域及生命周期

    Bean的作用域 在bean声明时它有一个scope属性,它是用于描述bean的作用域. 可取值有: singleton:单例 代表在spring ioc容器中只有一个Bean实例 (默认的scope ...

  3. Spring -Bean的作用域

    在 Spring 中, 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域. 默认情况下 bean 是单例的 但有的时候, bean 就不能使单例的. 例如: Str ...

  4. Spring Bean的作用域(作用范围)

    文章目录 scope 1. 注解方式配置1.1 测试singleton1.2 测试prototype 2. XML方式配置 在Spring中使用 scope来表示一个bean定义对应产生实例的类型,也 ...

  5. 说说 Spring Bean 的作用域

    配置文件中定义 Bean 时,我们不但可以配置 Bean 的属性值以及相互之间的依赖关系,还可以定义 Bean 的作用域 .作用域会对 Bean 的生命周期和创建方式产生影响 . Bean 的作用域类 ...

  6. spring Bean的作用域(注解 单例 多例)

    通过@Scope注解,指定Bean的作用域(默认是 singleton 单例) 回顾:XML的方式<bean id="" class="" scope=& ...

  7. spring bean scope作用域及多线程安全问题场景分析

    2019独角兽企业重金招聘Python工程师标准>>> Scope作用域 在 Spring IoC 容器中具有以下几种作用域: singleton:单例模式,在整个Spring Io ...

  8. Spring Bean的作用域之prototype

    Spring中Bean的默认最用域是单例,即singleton prototype是只在每次getBean的时候都去重新创建一个对象.下面我们来掩饰一下这种场景 使用SpringBoot项目.创建两个 ...

  9. spring之bean的作用域scope的值的详解

    今天研究了一下scope的作用域.默认是单例模式,即 scope="singleton".另外scope还有prototype.request.session.global ses ...

  10. Spring支持的几种bean的作用域

    1.singleton : bean在每个Spring ioc 容器中只有一个实例. 2.prototype:一个bean的定义可以有多个实例. 3.request:每次http请求都会创建一个bea ...

最新文章

  1. DFT,DTFT,DFS,FFT之间的关系以及序列补零和插值对频域的影响
  2. LoadRunner中常见参数和变量
  3. Pandas 4 个小 trick,都很实用!
  4. 【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信
  5. html5爱情树怎么修改,jQuery结合HTML5制作的爱心树表白动画
  6. flowable 多人签收_业务流程 BPM、工作流引擎、Flowable、Activiti
  7. ChaiNext:大盘调整,主流币种还未稳住阻力位
  8. [导入]FtpClient Library升级到4.x
  9. Mysql binlog 解析
  10. php文件的锁定机制
  11. 【洛谷试炼场】普及练习场——字符串处理
  12. EyouCMS瀑布流分页详细教程
  13. 集成运算放大器的应用——放大、加减、跟随、(滞回)比较器、阻抗匹配
  14. Paragon Camptune X for Mac(Mac磁盘分区工具) V10.13.433免费版
  15. 通过JS检测360浏览器
  16. 磁盘阵列RAID卡组建设置
  17. 逆波兰式的产生及计算(C++/Java)---编译原理
  18. 新的3D地图制图技术改变了全球定位的游戏规则
  19. c语言教程——简单易懂
  20. 来谈谈绿萝算法2.0对SEO产生的影响

热门文章

  1. 进阶学习(3.7) Flyweight Pattern 享元模式
  2. 网络推广是做什么的知道网站做301定向跳转对优化有什么帮助?
  3. 如何优化才能赢得搜索引擎“欢心”,提升抓取量?
  4. 浅析如何从比值得出网站优化效果的好坏?
  5. 外链对网站SEO优化起什么作用?
  6. 网络优化常见专业术语详解
  7. 每个网站SEO优化人员都要熟知的三大图片优化技巧
  8. java 括号匹配_java---括号匹配
  9. sdi线缆标准_Roland V1SDI——专业、便携、高性价比的SDI摄像机直播解决方案
  10. 列名必须是一个字符串或者数组_我爱Julia之入门-078(字符串08)