当对象的默认生命周期是单例时,并发在 SpringBoot 中是如何工作的
How concurrency works in SpringBoot when the default lifetime of objects is singleton
在 ASP.NET 中,在 IoC 容器中创建的对象的默认生命周期是针对每个 Web 请求的。在学习SpringBoot + Webflux的过程中,发现IoC容器默认创建的生命周期(Bean、Repository、Service等)是单例的。我知道我可以像这样更改默认范围:
@Scope("prototype")
但我还没有找到使用它的例子。所以如果 IoC 将所有对象都创建为单例,为什么没有并发问题。谁能给我解释一下。
这是个好问题。一般来说,在并发性是一个问题的地方,例如数据库层的事务上下文,springbook 使用基于线程的锁定机制。参见示例 1.2. Understanding the Spring Framework Transaction Abstraction。否则,是的,任何注入 CDI 的东西都是单例,除非另有特别注释。这意味着您不应在 @Component
或 @Service
class 中保留状态变量。只要方法仅使用传入的参数或方法的局部变量,并发性就不是问题,因为在堆栈上创建的变量对于每次调用都是唯一的。我看到一个应用程序一直运行良好,直到两个人同时登录。
如果你必须有一个带有状态变量的 class 你需要做一个 class 的 new
。
每个 spring-context 都是用一个唯一的线程创建的,因此在创建或注入非无状态对象的情况下,状态信息将附加到在其自己的线程中运行的 spring-context。
另见 How does Spring bean Handle concurrency
在 ASP.NET 中,在 IoC 容器中创建的对象的默认生命周期是针对每个 Web 请求的。在学习SpringBoot + Webflux的过程中,发现IoC容器默认创建的生命周期(Bean、Repository、Service等)是单例的。我知道我可以像这样更改默认范围:
@Scope("prototype")
但我还没有找到使用它的例子。所以如果 IoC 将所有对象都创建为单例,为什么没有并发问题。谁能给我解释一下。
这是个好问题。一般来说,在并发性是一个问题的地方,例如数据库层的事务上下文,springbook 使用基于线程的锁定机制。参见示例 1.2. Understanding the Spring Framework Transaction Abstraction。否则,是的,任何注入 CDI 的东西都是单例,除非另有特别注释。这意味着您不应在 @Component
或 @Service
class 中保留状态变量。只要方法仅使用传入的参数或方法的局部变量,并发性就不是问题,因为在堆栈上创建的变量对于每次调用都是唯一的。我看到一个应用程序一直运行良好,直到两个人同时登录。
如果你必须有一个带有状态变量的 class 你需要做一个 class 的 new
。
每个 spring-context 都是用一个唯一的线程创建的,因此在创建或注入非无状态对象的情况下,状态信息将附加到在其自己的线程中运行的 spring-context。
另见 How does Spring bean Handle concurrency