springboot教程-选择单例还是多例

单例的应用场景

如 Controller、service、dao,没必要每个请求都新建一个对象,既耗费CPU、又耗费内存
以下情况一般适合单例:

  • 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  • 没有成员变量的类
  • 频繁访问数据库或文件的类
  • 其他要求只有一个对象的场景

多例的应用场景

有成员变量的 service

单例的问题

service

增加 name 成员变量,get、set方法

@Service
public class StudentSrvImpl implements IStudentService {

    private String name;

    public StudentSrvImpl(){
        System.out.println("StudentSrvImpl构造方法"+this);
    }
    @Override
    public List<Student> query() {
        System.out.println("调用 StudentSrvImpl 的query()方法");
        return null;
    }
    public void save(Student student){
        System.out.println("调用 StudentSrvImpl 的save()方法");
        System.out.println(student.toString());
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

第一个Controller

@RestController
public class StudentCtrl {

    @Autowired
    private IStudentService studentSrv;

    @RequestMapping("/test")
    public JsonResult test() throws InterruptedException {
        StudentSrvImpl imp=(StudentSrvImpl)studentSrv;
        System.out.println(this.getClass()+"::设置名字为:李雷");
        imp.setName("李雷");
        Thread.sleep(5000);
        System.out.println(this.getClass()+"::"+imp.getName());

        return new JsonResult(0,"执行成功!");
    }
}

第二个Controller

@RestController
public class StudentCtrl2 {

    @Autowired
    private IStudentService studentSrv;


    public StudentCtrl2(){
        System.out.println("StudentCtrl()构造方法");
    }

    @RequestMapping("/test2")
    public JsonResult test() throws InterruptedException {
        StudentSrvImpl imp=(StudentSrvImpl)studentSrv;
        System.out.println(this.getClass()+"::设置名字为:韩梅梅");
        imp.setName("韩梅梅");
        System.out.println(this.getClass()+"::"+imp.getName());

        return new JsonResult(0,"执行成功!");
    }
}

执行

先访问 http://localhost:8080/test ,然后立即访问 http://localhost:8080/test2

执行流程:

  1. 第一个Controller先修改 service 的name为 李雷,然后延迟5秒

  2. 然后第二个Controller修改 service 的name为 韩梅梅,然后打印name值

  3. 最后,第一个Controller打印name值,此时显示的是 韩梅梅

总结

单例模式下,StudentSrvImpl 的成员变量会被多个Controller修改,此时会导致数据混乱

当有成员变量,而且成员变量的值会改变时,就不要使用单例模式,否则会互相干扰,此时应该用多例模式

解决

使用多例模式,在 service 加上 @Scope("prototype") 注解,如下:

@Service
@Scope("prototype")
public class StudentSrvImpl implements IStudentService {
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值