Spring MVC不要在@Service bean中保存状态

先看这么一段代码:

@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");}// ... ...}

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

转载于:https://www.cnblogs.com/gcczhongduan/p/5243104.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257606.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java class 关键字_java关键字及其作用

一、 关键字总览:访问控制privateprotectedpublic类,方法和变量修饰符abstractclassextendsfinalimplementsinterfacenativenewstaticstrictfpsynchronizedtransientvolatile程序控制breakcontinuereturndowhileifelseforinstanceofswitchcasedefault错误处理trycatchthrowthro…

3.过滤数据 ---SQL

一、使用WHERE子句 SELECT prod_name, prod_price FROM Products WHERE prod_price 3.49; 输出▼ prod_name prod_price ------------------- ---------- Fish bean bag toy 3.49 Bird bean bag toy 3.49 Rabbit bean bag toy 3.49 分析▼ 这条语句从products表中检索两个列&a…

IOS-C语言第8天,Struct (结构体)

转载于:https://www.cnblogs.com/xiangrongsu/p/4309160.html

Win2D 入门教程 VB 中文版 - 防止内存泄漏

避免内存泄漏 本文从微软官方文档翻译 http://microsoft.github.io/Win2D/html/RefCycles.htm 如果文档有问题,可以在 https://github.com/Nukepayload2/Win2dDocVB发 Issue,也可以直接回复。 当在托管的 XAML 应用程序中使用 Win2D 控件,需要…

java concurrent 锁_java并发机制锁的类型和实现

synchronized 和 volatile,是最基础的两个锁!volatile是轻量级锁,它在多核处理器开发中保证了共享变量的可见性。即当一个线程修改一个共享变量时,其他线程能够读到这个修改的值。它比syncronized使用和成本更低。要说volatile的实…

JAXB和XStream比较

这两东东本质上是有差别的,JAXB称为OX binding工具,XStream应该算序列化工具,但OX binding工具也会marshall和unmarshall,所以包含了序列化这一部分。序列化工具不一定需要提供binding的功能。既然都玩序列化,那就简单…

【起航计划 011】2015 起航计划 Android APIDemo的魔鬼步伐 10 App-Activity-Reorder Activities 后退栈 Intent FLAG...

Reorder Activities 示例有四个相关的Activitives: ReorderOnLaunch, ReorderTwo,ReorderThree, ReorderFour。其中ReorderOnLaunch为主Activity,ReorderOnLaunch启动ReorderTwo ,ReorderTwo启动 ReorderThree,ReorderThree启动 ReorderFour。…

java date dateformat_java中Date与DateFormat的格式输出

一、DateFormatjava.text.DateFormat使用 getDateInstance 来获取该国家/地区的标准日期格式。另外还提供了一些其他静态工厂方法。使用 getTimeInstance 可获取该国家/地区的时间格式。使用 getDateTimeInstance 可获取日期和时间格式。可以将不同选项传入这些工厂方法&#x…

spartan6不能直接把时钟连到IO上

1、问题的提出:spartan6中不允许时钟信号直接连到IO口上面? 2、解决办法:ODDR2的使用 ODDR2Primitive: Double Data Rate Output D Flip-Flop with Optional Data Alignment, Clock Enable and Programmable Synchronous or Asynchronous Set…

STL容器及适配器

STL容器 1.序列式容器 : vector,deque,list。 每个元素都有固定的位置(取决于插入的时机和位置,与元素值无关)。 vector 特点: 将一个元素置于一个动态数组中加以管理,可以随机存取元…

Html5 Canvas斗地主游戏

过完年来公司,没什么事,主管说研究下html5 游戏,然后主管就给了一个斗地主的demo,随后我就开始看代码, 现在我看了html5以及canvas相关知识和斗地主的demo后,自己用demo上的素材试着写了个斗地主&#xff0…

java流的传递方式是_如何在方法中流式传输Java List(Varargs)的值?

我有以下方法:public static List getValuesExclusion(A exclusion) {return Arrays.stream(values()).filter(item -> item ! exclusion).collect(Collectors.toList());}//this function returns enum list of A types that has no A typeexclusion现在我想将它…

JAVA作业——JAVA课程的总结及学习计划

JAVA作业——JAVA课程的总结及学习计划 NO.1 总结 在上一年的学习中,对JAVA语言比较陌生,英语基础不好,so学习起来有点困难,对JAVA的一些语法和编程记得比较少。 NO.2 计划 对过去一年的认真反思之后,我的计划如下&…

由LintCode问题子集出发,浅析ArrayList的拷贝问题

在做LintCode上的递归类题目子集时&#xff0c;我一开始的想法是递归到最后一层即单元素时然后开始逐层返回&#xff0c;产生相应的每层的子集并添加到最终的结果中去。于是乎有了以下代码&#xff1a; public List<List<Integer>> findSolution(int[] nums, int b…

大小端模式详解

http://www.cnblogs.com/xinsheng/archive/2012/04/18/2455039.html 端模式&#xff08;Endian&#xff09;的这个词出自Jonathan Swift书写的《格列佛游记》。这本书根据将鸡蛋敲开的方法不同将所有的人分为两类&#xff0c;从圆头开始将鸡蛋敲开的人被归为Big Endian&#xf…

.NET 跨平台服务端资料

OWIN Web API: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api 用于写API的 OWIN SignalR: http://www.dotnetcurry.com/signalr/915/owin-katana-signalr-web-server 用于写即时通讯的转载于:https://www.cnblogs.com/Jarvin…

mysql的查询、子查询及连接查询

一、mysql查询的五种子句 where子句&#xff08;条件查询&#xff09;&#xff1a;按照“条件表达式”指定的条件进行查询。 group by子句&#xff08;分组&#xff09;&#xff1a;按照“属性名”指定的字段进行分组。group by子句通常和count()、sum()等聚合函数一起使用。 h…

BZOJ-1192-鬼谷子的钱袋

描述 鬼谷子非常聪明&#xff0c;正因为这样&#xff0c;他非常繁忙&#xff0c;经常有各诸侯车的特派员前来向他咨询时政。有一天&#xff0c;他在咸阳游历的时候&#xff0c;朋友告诉他在咸阳最大的拍卖行&#xff08;聚宝商行&#xff09;将要举行一场拍卖会&#xff0c;其中…

lamp 独立mysql_lamp or lnmp 环境搭建之独立安装mysql数据库

lamp or lnmp 环境搭建,如果mysql 是独立安装的则需要授权&#xff1a;单独一台服务器独立安装mysql安装后&#xff0c;优化服务器。授权实例如下&#xff1a;创建用户CREATE USER demo IDENTIFIED BY “passwd123”;授权使用mysql数据库下面的所有表GRANT ALL PRIVILEGES ON m…

item 24: 区分右值引用和universal引用

本文翻译自《effective modern C》&#xff0c;由于水平有限&#xff0c;故无法保证翻译完全正确&#xff0c;欢迎指出错误。谢谢&#xff01; 博客已经迁移到这里啦 古人曾说事情的真相会让你觉得很自在&#xff0c;但是在适当的情况下&#xff0c;一个良好的谎言同样能解放你…