Spring的Controller怎样保证线程安全问题分析
我们先来看下⾯的代码,判断⼀下两个接⼝请求的值分别多少。
import com.del.system.OptResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @author ybc
* @date 2020/08/05 21:30
*/
@RestController
public class TestController {
//定义测试成员变量
private int num =0;
@RequestMapping(value ="/testOne",method = RequestMethod.GET)
public OptResult<Integer>testOne(){
return new OptResult<>(OptResult.OptStat.OK,++num);
}
@RequestMapping(value ="/testTwo",method = RequestMethod.GET)
public OptResult<Integer>testTwo(){
return new OptResult<>(OptResult.OptStat.OK,++num);
}
}
如果这个Controller是线程安全的,两个接⼝请求的值应该是相同的。
问题验证
请求接⼝testOne返回结果为:
请求接⼝testTwo返回结果为:
两个接⼝返回的值是不同的,显然线程不安全。controller单例还是多例
下⾯我们来改造⼀下代码,让controller增加作⽤多例 @Scope(“prototype”),重新运⾏程序。
@RestController
@Scope("prototype")
public class TestController {
//定义测试成员变量
private int num =0;
@RequestMapping(value ="/testOne",method = RequestMethod.GET)
public OptResult<Integer>testOne(){
return new OptResult<>(OptResult.OptStat.OK,++num);
}
@RequestMapping(value ="/testTwo",method = RequestMethod.GET)
public OptResult<Integer>testTwo(){
return new OptResult<>(OptResult.OptStat.OK,++num);
}
}
请求接⼝testOne返回结果为:
请求接⼝testTwo返回结果为:
通过上述两种对⽐的结果我们可以发现,单例是不安全的,会导致属性重复使⽤。
解决⽅案
1. 尽量避免在controller中定义成员变量。
2. 如果必须定义成员变量时候,需要通过注解@Scope(“prototype”),将其设置为多例模式。
3. 在Controller中使⽤ThreadLocal变量

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。