先看这么一段代码:

@Service
public class AccountService {private String message;public void foo1() {if (true) {this.message = "a";} else {this.message = "b";}}public void foo2() {// 改动this.message的代码...// ... ...}
}

假设你打算在@Controller里这么调用AccountService :

accountService.foo1();model.addAttribute(accountService.getMessage());

那么就有线程安全的危急了。

问题原因

在Spring中。bean的默认scope是singleton,也就是说容器中仅仅有一个bean的实例。而在Java Web环境中,webserver会为每个请求创建一个线程来处理它。这样一来。在@Controller中调用@Service bean的方法就会导致有多个线程在运行@Service方法。比如线程A在运行foo1()方法,线程B在运行foo2()方法。

那么问题来了,多个线程同一时候读写message成员变量。就可能让getMessage()方法返回错误的值

解决方法

1. 将@Service bean的scope改为 "request",即:
@Service
@Scope("request")
public class AccountService {private String message;

这样Spring会为每个请求分别创建一个AccoutService对象,每个线程都有自己的message变量。就不会出错了。

但坏处是创建@Service bean的开销往往比較大,会导致程序性能下降。

2. 使用不可变对象(Immuable Object)封装message变量
定义例如以下类:
class MessageWrapper {private String message;public MessageWrapper(String msg) {this.message = msg;}// 仅仅提供get方法public String getMessage() {return this.message;}
}

AccountService的foo1()方法改动例如以下:

@Service
public class AccountService {public MessageWrapper foo1() {if (true) {return new MessageWrapper("a");} else {return new MessageWrapper("b");}// ... ...}

这样便能够完美避免线程安全问题,又不会带来过多的额外开销。

Spring MVC不要在@Service bean中保存状态相关推荐

  1. 在C 函数中保存状态:registry、reference和upvalues

    在C函数中保存状态:registry.reference和upvalues      C函数能够通过堆栈来和Lua交换数据,但有时候C函数须要在函数体的作用域之外保存某些Lua数据.那么我们想到全局变 ...

  2. 程序中保存状态的方式之Cookies

    程序中保存状态的方式之 Cookies,之前写过一篇关于ViewState的.现在继续总结Cookies方式的 新建的测试页面login <%@ Page Language="C#&q ...

  3. Spring MVC page render时jsp中元素相对路径的解决办法

    前段时间做了用Spring Security实现的登录和访问权限控制的功能,但是page render使用的是InternalResourceResolver,即在spring的servlet配置文件 ...

  4. spring mvc 接收表单 bean

    spring MVC如何接收表单bean 呢? 之前项目中MVC框架一直用struts2,所以我也就按照struts2 的思维来思考 页面loginInput.jsp: Html代码   <?x ...

  5. 【jeecg-mybatis版本】 mybatis+spring mvc 完美整合方案 查询,保存,更新,删除自动生成

      Jeecg-mybatis-framework 版本 简要说明 JEECG[J2EE Code Generation]是一款基于代码生成器的J2EE智能开发框架,借助该框架可以节省50%的工作量, ...

  6. mybatis+spring mvc 完美整合方案 查询,保存,更新,删除自动生成

    Jeecg-Mybatis版本代码生成器演示视频 代码下载:JEECG-mybatis参考学习版本 简要说明  JEECG[J2EE Code Generation]  代码生成:根据表生成对应的Be ...

  7. 【jeecg-mybatis版本】 mybatis+spring mvc 完美整合方案 查询,保存,更新,删除自动生成...

    Jeecg-Mybatis版本代码生成器演示视频 http://pan.baidu.com/share/link?shareid=243717&uk=2668473880   简要说明  JE ...

  8. IDEA中Spring MVC实现图片上传并显示

    我们都知道web项目需要部署到tomcat服务器中运行 那么,我们又是如何通过tomcat来访问存放在本地磁盘中的图片呢?,通过tomcat访问本地图片,需要配置虚拟路径,下面介绍两种配置虚拟路径的方 ...

  9. Spring MVC中@RequestParam和@PathVariable批注之间的区别?

    Spring MVC框架是在Java世界中开发Web应用程序最流行的框架之一,它还提供了一些有用的注释,可以从传入的请求中提取数据并将请求映射到控制器,例如@ RequestMapping,@ Req ...

最新文章

  1. git 切换分支_简单git操作
  2. [原创]ExtAspNet秘密花园(十六) — 表格之排序与分页
  3. 一套模块化数据中心培训资料
  4. Struts2 控制台不打印异常的解决方案
  5. c语言case接收字符,switch-case-break:字符释义 | 新思维:C语言程序设计
  6. Jquery调用ajax参数说明
  7. https证书相关概念
  8. 再过十年,电脑游戏会被手机游戏完全取代吗?
  9. NOIP2017 Day1 T1 小凯的疑惑
  10. 《PaaS程序设计》一1.2 云能为创新做什么
  11. 用C语言实现俄罗斯方块游戏
  12. android车载桌面,车载桌面Car Launcher Pro
  13. HTML班级网站实例(笔记2)
  14. 综述:环境中的噬菌体宿主互作
  15. Coprime Triples——CodeChef - COPRIME3
  16. Web前端系列技术之移动端CSDN会员页面复刻(动态完整版)
  17. 2022年湖南省自考考试幼儿园教育活动设计与组织练习题及答案
  18. Excel表格标题重复打印
  19. php幻灯片图片不显示不出来,首页幻灯片中图片无法显示的解决办法
  20. java期未项目_Java项目实战知到期末答案

热门文章

  1. javaio流_万字长文+思维导图帮你梳理 Java IO 流,还学不会你来打我(值得收藏)...
  2. tensorflow中sess.run第一个参数衣服不能随便穿
  3. java jxl创建多个sheet,使用jxl导出excel时怎么创建多个sheet | 学步园
  4. 笔记-项目立项管理-项目建议书
  5. 项目立项管理:项目可行性分析和项目审批
  6. Three.js中实现点击按钮添加删除旋转立方体
  7. Anuglar中的常用通道-大小写转换、日期转换、小数位数、Json、slice、管道链
  8. SpringCloud-使用路由网关的服务过滤功能-拦截登录前是否有token为例
  9. Mysql、Oracle、SQLServer等数据库参考文档免费分享下载
  10. Eclipse新建SpringBoot后pom.xml代码