How does Spring Controller ensure thread safety

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
Insert picture description here
request interface testOne is: the return result of the request interface testTwo is:
Insert picture description here
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
Insert picture description here
request interface testOne is: The return result of the request interface testTwo is: Through the results of the
Insert picture description here
above two comparisons, we can find that the singleton is insecure and will cause the attribute to be reused.

solution

  1. Try to avoid defining member variables in the controller.
  2. If you must define a member variable, you need to pass the annotation @Scope("prototype") to set it to multi-case mode.
  3. Use ThreadLocal variable in Controller

Guess you like

Origin blog.csdn.net/cyb_123/article/details/107826018