problem analysis
Let's first look at the following code to determine the value of the two interface requests.
import com.sun.proxy.model.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);
}
}
If this Controller is thread-safe, the values requested by the two interfaces should be the same.
Problem verification
The return result of the
request interface testOne is: the return result of the request interface testTwo is:
the values returned by the two interfaces are different, which is obviously thread-unsafe.
Let's modify the code, let the controller add more examples @Scope("prototype"), and rerun the program.
@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);
}
}
The return result of the
request interface testOne is: The return result of the request interface testTwo is: Through the results of the
above two comparisons, we can find that the singleton is insecure and will cause the attribute to be reused.
solution
- Try to avoid defining member variables in the controller.
- If you must define a member variable, you need to pass the annotation @Scope("prototype") to set it to multi-case mode.
- Use ThreadLocal variable in Controller