在Web应用中,如果能够实例化在会话和请求范围内共享的bean,那将是非常有价值的事情。例如,在典型的电子商务应用中,可能会有一个bean代表用户的购物车。如果购物车是单例的话,那么将会导致所有的用户都会向同一个购物车中添加商品。另一方面,如果购物车是原型作用域的,那么在应用中某一个地方往购物车中添加商品,在应用的另外一个地方可能就不可用了,因为在这里注入的是另外一个原型作用域的购物车。
就购物车bean来说,会话作用域是最为合适的,因为它与给定的用户关联性最大。要指定会话作用域,我们可以使用@Scope注解,它的使用方式与指定原型作用域是相同的:

@Componet

@Scope(

  value=webApplicationContext.SCOPE_SESSION,

  proxyModel=ScopeProxyModel.INTERFACES

)

public ShoppingCart cart{......}

这里,我们将value设置成了WebApplicationContext中的SCOPE_SESSION常量(它的值是session)。这会告诉Spring为Web应用中的每个会话创建一个ShoppingCart。这会创建多个ShoppingCart bean的实例,但是对于给定的会话只会创建一个实例,在当前会话相关的操作中,这个bean实际上相当于单例的。
要注意的是,@Scope同时还有一个proxyMode属性,它被设置成了ScopedProxyMode.INTERFACES。这个属性解决了将会话或请求作用域的bean注入到单例bean中所遇到的问题。在描述proxyMode属性之前,我们先来看一下proxyMode所解决问题的场景。

假设我们要将ShoppingCart bean注入到单例StoreService bean的Setter方法中,如下所示:

@Componet

public class StoreService{

  @Autowired

  public void setShoppingCart(ShoppingCart shoppingCart)

  {

    this.shoppingCart = shoppingCart;

  }

}

因为StoreService是一个单例的bean,会在Spring应用上下文加载的时候创建。当它创建的时候,Spring会试图将ShoppingCart bean注入到setShoppingCart()方法中。但是ShoppingCart bean是会话作用域的,此时并不存在。直到某个用户进入系统,创建了会话之后,才会出现ShoppingCart实例。
另外,系统中将会有多个ShoppingCart实例:每个用户一个。我们并不想让Spring注入某个固定的ShoppingCart实例到StoreService中。我们希望的是当StoreService处理购物车功能时,它所使用的ShoppingCart实例恰好是当前会话所对应的那一个。Spring并不会将实际的ShoppingCart bean注入到StoreService中,Spring会注入一个到ShoppingCart bean的代理,如图3.1所示。这个代理会暴露与ShoppingCart相同的方法,所以StoreService会认为它就是一个购物车。但是,当StoreService调用ShoppingCart的方法时,代理会对其进行懒解析并将调用委托给会话作用域内真正的ShoppingCart bean。
现在,我们带着对这个作用域的理解,讨论一下proxyMode属性。如配置所示,proxyMode属性被设置成了ScopedProxyMode.INTERFACES,这表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean。
如果ShoppingCart是接口而不是类的话,这是可以的(也是最为理想的代理模式)。但如果ShoppingCart是一个具体的类的话,Spring就没有办法创建基于接口的代理了。此时,它必须使用CGLib来生成基于类的代理。所以,如果bean类型是具体类的话,我们必须
要将proxyMode属性设置为ScopedProxyMode.TARGET_CLASS,以此来表明要以生成目标类扩展的方式创建代理。
尽管我主要关注了会话作用域,但是请求作用域的bean会面临相同的装配问题。因此,请求作用域的bean应该也以作用域代理的方式进行注入。

spring:使用会话和请求作用域的更多相关文章

  1. (三)Spring 高级装配 bean的作用域@Scope

    1.默认情况下,spring通过@Autowared注入的bean是单例的bean,但有些情况是不满足的,例如:购物车,每个会话,或每个用户登录使用的购物车都是独立的 spring的定义的作用域: a ...

  2. Spring MVC的映射请求

    一.SpringMVC常用注解 @Controller 声明Action组件 @Service    声明Service组件    @Service("myMovieLister" ...

  3. Spring基础11——Bean的作用域

    1.Bean的作用域种类 Spring中的bean的作用域分为四种:singleton.prototype.session.request,后两种很少使用,下面我们主要来学习前两种 2.singlet ...

  4. 【spring boot】spring boot 前台GET请求,传递时间类型的字符串,后台无法解析,报错:Failed to convert from type [java.lang.String] to type [java.util.Date]

    spring boot 前台GET请求,传递时间类型的字符串,后台无法解析,报错:Failed to convert from type [java.lang.String] to type [jav ...

  5. Spring MVC中forward请求转发2种方式(带参数)

    Spring MVC中forward请求转发2种方式(带参数) http://www.51gjie.com/javaweb/956.html  

  6. spring mvc 文件下载 get请求解决中文乱码问题

    方案简写,自己或有些基础的可以看懂,因为没时间写的那么详细 方案1 spring mvc解决get请求中文乱码问题, 在tamcat中server.xml文件 URIEncoding="UT ...

  7. (转)配置Spring管理的bean的作用域

    http://blog.csdn.net/yerenyuan_pku/article/details/52833477 Spring管理的bean的作用域有: singleton 在每个Spring ...

  8. Spring MVC 异步处理请求,提高程序性能

    原文:http://blog.csdn.net/he90227/article/details/52262163 什么是异步模式 如何在Spring MVC中使用异步提高性能? 一个普通 Servle ...

  9. Spring mvc 启动 和 请求分发

    Spring mvc 启动 和 请求分发 启动加载: abstract class HttpServletBean extends HttpServlet void init() initServle ...

随机推荐

  1. 控制台程序的中文输出乱码问题(export LC_CTYPE=zh_CN.GBK,或者修改/etc/sysconfig/i18n为zh_CN.GBK。使用setlocale(LC_CTYPE, "");会使用默认办法。编译器会将源码做转换成Unicode格式,或者指定gcc的输入文件的编码参数-finput-charset=GBK。Linux下应该用wprintf(L"%ls/n",wstr))

    今天发现用securecrt登陆时,gcc编译出错时会出现乱码,但直接在主机的窗口界面下用Shell编译却没有乱码.查看了一下当时的错误描述,发现它的引号是中文引号,导致在SecureCRT中显示出错 ...

  2. 通过天天模拟器加burpsuite抓取手机app流量

    通过天天模拟器,代理抓取安卓app数据包.也可以抓取https. 1.下载天天模拟器,官方下载即可,下载安装. 2.启动天天模拟器,设置代理,点击上方wlan设置图标,打开wlan设置,如下: 3.鼠 ...

  3. LINUX 文件/组/帮助/权限/文件压缩/管道

    Linux文件/目录详解 常用文件路径的作用 /var/log/messages 系统类的日志文件 /var/log/secure 登录日志文件 /var/spool/cron 定时任务目录 /etc ...

  4. Symfony4 数据库连接

    代码 https://github.com/liudianpeng/BlogMVC-Symfony4 在 .env 文件可以调整一下数据库连接信息 ###> doctrine/doctrine- ...

  5. seaborn(matplotlib)画图,linux系统中文乱码等问题解决

    data = pd.read_json(json.dumps(issue_dpl)) # set pic size plt.figure(figsize=(13, 5)) sns.set_style( ...

  6. STM32 ~ CH340在STM32实现一键下载电路

    在做基于STM32的多功能MP3播放器的课题时,在程序下载这部分时借鉴了正点原子开发板上的一键下载电路,采用CH340G这款芯片设计. 在画PCB初期原理图部分,对采用CH340G设计的一键下载电路不 ...

  7. 流量分析系统---echarts模拟迁移中 ,geocoord从后台获取动态数值

    由于在echarts的使用手册中说了 {Object} geoCoord (geoCoord是Object类型) ,所以不能用传统的字符串拼接或数组的方式赋值.在后台的controller中用Map& ...

  8. yii2判断数据库字段is null

    $query = new Query; $query->select('ID, City,State,StudentName') ->from('student') ->]) -&g ...

  9. Linux文件系统管理 挂载命令mount

    概述 mount命令用来挂载Linux系统外的文件. Linux 中所有的存储设备都必须挂载之后才能使用,包括硬盘.U 盘和光盘(swap 分区是系统直接调用的,所以不需要挂载).不过,硬盘分区在安装 ...

  10. [原创]spring及springmvc精简版--AOP

    接上一篇:[原创]spring及springmvc精简版--IOC 理解AOP.java是一种面向对象的语言.而AOP是面向切面,在我看来是面向逻辑或者业务编程,它是对一组逻辑的抽象和分配. 经典例子 ...