SpringMVC中的Bean单例模式和并发相关问题

  1. SpringMVC中的controller单例模式

我们知道在Spring框架中,所有的Bean都是默认单例模式,Controller也是一个bean,所以我们默认的Controller也是单例模式,所以我们需要考虑的就是一个Controller类中并发访问安全性。
如以下代码:

 import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class testController {
    private int Product_Num=1000;//默认每个用户可以购买的促销商品有1000件

    @RequestMapping("/First")
    public void First(){
        System.out.println(Product_Num--);
    }

    @RequestMapping("/Second")
    public void Second(){
        System.out.println(Product_Num--);
    }
}

我们先访问First,然后访问Second,访问成员变量Product_Num。我们就会发现,Second在控制台输出的是9998。这样没办法满足我们的场景。所以我们需要用到并发。但是关于Controller的并发有很多方法可以实现。
第一种就是:不要共享成员变量 代码略!
第二种就是:把相关Controller类变成多例模式代码如下:

import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Scope(scopeName = "mulExample")//添加相关注解,使单例Bean变化为多例Bean
@RestController
public class testController {
    private int Product_Num=1000;//默认促销商品有1000件

    @RequestMapping("/First")
    public void First(){
        System.out.println(Product_Num--);
    }

    @RequestMapping("/Second")
    public void Second(){
        System.out.println(Product_Num--);
    }
}

这种方法就是保障每一个访问都是一个新的Controller新对象,这样保障了不会出现共享变量的相关问题。
第三种就是:使用threadLocal解决

import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Scope(scopeName = "mulExample")//添加相关注解,使单例Bean变化为多例Bean
@RestController
public class testController {
    private int Product_Num=1000;//默认促销商品有1000件
    
    private ThreadLocal<Integer> threadLocal=new ThreadLocal<>();

    public ThreadLocal<Integer> getThreadLocal() {
        return threadLocal;
    }

    public void setThreadLocal(ThreadLocal<Integer> threadLocal) {
        this.threadLocal = threadLocal;
    }
    

    @RequestMapping("/First")
    public void First(){
        System.out.println(Product_Num--);
    }

    @RequestMapping("/Second")
    public void Second(){
        System.out.println(Product_Num--);
    }
}

版权声明:本文为weixin_52033496原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。