详解Spring中singleton bean如何同时服务多个请求
正文
当我开始学习 Spring 时,两个“难”的问题主要在我脑海中盘旋:
- 如何创建单例 bean,然后如何在不同的类中自动装配单个 bean?
- 想象一下这种情况:
有 2 个用户,其中一个想要登录,另一个想要同时在我们的应用程序中创建报告。login 和 createReport 方法都使用范围为单例的 userService bean。在这种情况下,这些方法是否按顺序使用该单例 bean?否则 singleton bean 如何同时处理多个请求?
回答他们并不像我想的那么困难。只是需要澄清简单但重要的要点。这就是为什么我会尝试用基本的代码示例来描述它们。让我们开始:
先讲一下Spring容器
因为我认为这会帮助你在脑海中更好地描述过程。
Spring 容器在其中创建 bean。创建所需的 bean 后,它会注入它们的依赖项。容器通过读取配置元数据(XML 或 Java 注释)来获取指令。因此,在初始化 Spring 容器后,您的应用程序就可以使用了,如下图所示:
当你像下面这样定义一个 bean 定义时,你告诉容器它必须只为容器中的那个 bean 定义创建一个实例:
<bean id=”accountDao” class=”…” scope=”singleton”/>
此单个实例存储在此类单例 bean 的缓存中。然后 Spring 容器将这个缓存的对象返回给具有该 bean 定义的 bean 的所有请求和引用:
如果我们想用 new() 运算符显示上面的示例,以描述 Spring 容器在应用程序启动时所做的简化视图,我们可以编写如下代码:
UserService userService = new UserService(); UserController userController = new UserController(); userController.userService = userService; ReportController reportController = new ReportController(); reportController.userService = userService
@RestController public class UserController { @Autowired private UserService userService; @GetMapping(value = "/login/{username}") public User login(@PathVariable(value = "username") String username){ System.out.println(Thread.currentThread().getName() + " ----------- " + username + " ----------- " + new Date()); return userService.login(username); } }
这些线程分别与单例 bean 一起工作。如何?
稍微谈谈 Java 中的内存分配
在 Java 中,每个对象都是在堆中创建的。堆是全局共享内存。这就是为什么每个线程都可以访问堆中的对象。
但是堆栈仅用于执行一个线程。在那个线程中,当一个方法被调用时,一个新的块会以 LIFO(Last-In-First-Out) 顺序在堆栈中创建。该块保存本地原始值和对方法中其他对象的引用。并且栈内存不能被其他线程访问。
所以当我们创建单例 bean 时,它驻留在堆中。由于可以从应用程序的任何位置访问堆,因此每个创建的线程都可以指向该单例 bean。这是怎么发生的?当线程请求单例bean时,它会(借助堆栈中的引用变量)引用堆中单例bean的字节码。所以多个线程可以同时引用单例bean。编译器将指向相同的字节码并简单地执行它并将方法特定值分别存储在堆栈中的相应块中。没有阻止编译器执行此操作的限制。Singleton 类对 JVM 的唯一限制是它只能在堆中拥有此类的一个实例。这就是为什么理想的单例 bean 必须是无状态的。否则可能会出现并发问题。
以上就是详解Spring中singleton bean如何同时服务多个请求的详细内容,更多关于Spring singleton bean多个请求的资料请关注脚本之家其它相关文章!
相关文章
SpringBoot使用Spring Cache高效处理缓存数据
Spring Cache是一个框架,只要简单加一个注解,就能实现缓存功能,本文主要介绍了SpringBoot使用Spring Cache高效处理缓存数据,感兴趣的可以了解一下2023-11-11Java SpringBoot 使用拦截器作为权限控制的实现方法
这篇文章主要介绍了Java SpringBoot 使用拦截器作为权限控制的实现,文中通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-10-10详解Java的MyBatis框架和Spring框架的整合运用
在Web端的SSH框架整合中Spring主要负责数据库处理,而引入MyBatis后二者的集成使用效果更佳,下面我们就来详解Java的MyBatis框架和Spring框架的整合运用2016-06-06@PathVariable和@RequestParam传参为空问题及解决
这篇文章主要介绍了@PathVariable和@RequestParam传参为空问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-11-11Spring Boot整合mybatis并自动生成mapper和实体实例解析
本文是小编给大家总结的关于Spring Boot整合mybatis并自动生成mapper和实体的内容,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧2018-05-05Spring4.0 MVC请求json数据报406错误的解决方法
这篇文章主要为大家详细介绍了Spring4.0 MVC请求json数据报406错误的解决方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-01-01
最新评论