Spring 的Controller 是单例or多例

      你什么也不肯放弃,又得到了什么?

背景:今天写代码遇到一个Controller 中的线程安全问题,那么Spring 的Controller 是单例还是多例的呢?若为单例又如何保证并发安全呢?

一、面试回答

Spring管理的Controller,即加入@Controller 注入的类,默认是单例的,因此建议:

1、不要在Controller 中定义成员变量;(单例非线程安全,会导致属性重复使用)

2、若必须要在Controller 中定义一个非静态成员变量,则通过注解@Scope("prototype"),将其设置为多例模式。

二、验证Controller 单例

验证代码:

 package com.ausclouds.bdbsec.tjt;

 import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; /**
* @author tjt
* @time 2020-08-25
* @desc 验证Controller 单例
*/
@Controller
@ResponseBody
@RequestMapping("/tjt")
public class TestSingleController { private long money = 10; @GetMapping("/test1")
public long testSingleOne(){
money = ++money;
System.out.println("/tjt/test1: the money I have: " + money);
return money;
} @GetMapping("test2")
public long testSingleTwo(){
money = ++money;
System.out.println("/tjt/test2: the money I have: " + money);
return money;
} }

-拍一拍

首先,访问 http://localhost:8088/test1,得到的答案是11

接着,再访问 http://localhost:8088/test2,得到的答案是 12

不难看出:同一个变量,两次访问得到不同的结果,很明显是线程不安全的。

验证截图:

 三、Controller 如何实现多例?

尽量不要在Controller 中定义成员变量,若必须要在Controller 中定义一个非静态成员变量,则通过注解@Scope("prototype"),将其设置为多例模式;或者是在Controller 中使用ThreadLocal 变量。

验证代码:

 package com.ausclouds.bdbsec.tjt;

 import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; /**
* @author tjt
* @time 2020-08-25
* @desc 验证Controller 单例
*/
@Controller
@ResponseBody
@Scope("prototype") // 将Controller 设置为多例模式
@RequestMapping("/tjt")
public class TestSingleController { private long money = 10; @GetMapping("/test1")
public long testSingleOne(){
money = ++money;
System.out.println("/tjt/test1: after use @Scope the money I have: " + money);
return money;
} @GetMapping("test2")
public long testSingleTwo(){
money = ++money;
System.out.println("/tjt/test2: after use @Scope the money I have: " + money);
return money;
} }

-拍一拍

在加上@Scope("prototype")后首先,访问 http://localhost:8088/test1,得到的答案是11

接着,再访问 http://localhost:8088/test2,得到的答案也是 11

不难看出:同一个变量,两次访问得到相同的结果。

验证截图:

四、作用域

其实,spring bean 的作用域除了上面使用的prototype 外,还有singleton、request、session 和global session 四种;其中request、session 和global session 主要运用在Web 项目中。

  • singleton:单例模式,当spring 创建applicationContext 容器的时候,spring会预初始化所有的该作用域实例,加上lazy-init 就可以避免预处理;
  • prototype:原型模式,每次通过getBean 获取该bean 就会新产生一个实例,创建后spring 将不再对其管理;
  • request:每次请求都新产生一个实例,和prototype 不同就是创建后,接下来的管理,spring依然在监听;
  • session:每次会话,同上;
  • global session:全局的web 域,类似于servlet 中的application。

你什么也不肯放弃,又得到了什么?

Spring 的Controller 是单例or多例的更多相关文章

  1. springboot默认创建的bean是单实还是多例

    转:https://blog.csdn.net/q1512451239/article/details/53122687 springboot默认创建的bean是单实还是多例 曾经面试的时候有面试官问 ...

  2. 转:【Spring MVC Controller单例陷阱】

    http://lavasoft.blog.51cto.com/62575/1394669/ Spring MVC Controller默认是单例的: 单例的原因有二:1.为了性能.2.不需要多例. 1 ...

  3. Spring MVC Controller单例陷阱

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://lavasoft.blog.51cto.com/62575/1394669 Spr ...

  4. spring的controller默认是单例还是多例

    转: spring的controller默认是单例还是多例 先看看spring的bean作用域有几种,分别有啥不同. spring bean作用域有以下5个: singleton:单例模式,当spri ...

  5. Spring5源码解析-Spring框架中的单例和原型bean

    Spring5源码解析-Spring框架中的单例和原型bean 最近一直有问我单例和原型bean的一些原理性问题,这里就开一篇来说说的 通过Spring中的依赖注入极大方便了我们的开发.在xml通过& ...

  6. SpringMVC中的Controller默认单例

    众所周知,Servlet是单例的. 在struts中,Action是多例的,每一个请求都会new出来一个action来处理. 在Spring中,Controller默认是单例的,多个请求都会访问同一个 ...

  7. Spring对象类型——单例和多例

    由于看淘淘商城的项目,涉及到了项目中处理spring中bean对象的两种类型,分别是单例和多例,就在此记录一下,方便加深理解,写出更加健壮的代码. 一.单例和多例的概述 在Spring中,bean可以 ...

  8. Spring容器-ApplicationContext的单例设计

    Spring容器-ApplicationContext的单例设计   每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会 ...

  9. SSM-Spring-05:Spring的bean是单例还是多例,怎么改变?

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- Spring的bean是单例的 它在Spring容器初始化的时候创建对象 可以修改为多例,在此bean节点中添 ...

随机推荐

  1. Maven——软件开发中一个神奇的项目管理工具

    由于本人是从c++转入从事JAVA工作的 所以很多东西要从头学起,相信有很多跟我一样的人吧,那么我们一起来学习. 今天我们一起来认识下Maven这个工具,很多人可能会问题了,为什么说是工具呢?不是写代 ...

  2. 学习python的几个资料网站

    菜鸟教程 https://www.runoob.com/python3/python3-tutorial.html https://www.runoob.com/python/python-tutor ...

  3. pandas_查看数据特征和统计信息

    # 查看数据特征和统计信息 import pandas as pd # 读取文件 dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\总结\Pyth ...

  4. c++ 第一天 变量、判断、循环

    C++介绍 语言的产生 C++ 由 Bjarne Stroustrup 于 1979 年在贝尔实验室开始设计开发的,由于C++ 进一步扩充和完善了 C 语言,是一种面向对象的程序设计语言 ,所以最初命 ...

  5. 11-14序列化模块之json、pickle、shelve

    序列化的目的 1.以某种存储形式使自定义对象持久化: 2.将对象从一个地方传递到另一个地方. 3.使程序更具维护性. 序列化--转向一个字符串数据类型序列--及时字符串 何处用到: 数据存储 网络上传 ...

  6. Windows10 无法完全关闭Hyper-V导致VirtualBox 虚拟机无法启动

    win10本来已经安装使用了VirtualBox. 突然心血来潮决定试试系统自带的虚拟机Hyper-V.发现并没有想象中的好用.随后在启用或关闭 Windows功能中关闭了Hyper-V. 这时我发现 ...

  7. IDEA操作jdbc总结

    今天学习IDEA操作JDBC,MySQL包导入到项目 // 1.注册数据库的驱动// Driver driver=new com.mysql.jdbc.Driver();// DriverManage ...

  8. Codechef July Challenge 2020 Division 1 记录

    目录 Missing a Point Chefina and Swaps Doctor Chef Chef and Dragon Dens LCM Constraints Weird Product ...

  9. Kubeflow实战: 入门介绍与部署实践

    更多内容关注专辑: 机器学习实战 1 介绍 Kubeflow是在k8s平台之上针对机器学习的开发.训练.优化.部署.管理的工具集合,内部集成的方式融合机器学习中的很多领域的开源项目,比如Jupyter ...

  10. C#LeetCode刷题-并查集

    并查集篇 # 题名 刷题 通过率 难度 128 最长连续序列   39.3% 困难 130 被围绕的区域   30.5% 中等 200 岛屿的个数   38.4% 中等 547 朋友圈   45.1% ...