gpt4 book ai didi

java - Spring Singleton 意味着类级别没有数据共享?

转载 作者:行者123 更新时间:2023-12-01 17:42:29 25 4
gpt4 key购买 nike

我很困惑。

Spring 的默认 bean 作用域是 Singleton。这意味着一旦您定义了类的 bean,每次新的“消息”传入时,它将由该类的同一实例进行处理。

但这也意味着您不能在该单例 bean 中拥有可变实例变量,因为该类的方法的下一次调用将看到过去调用的数据。

示例:计算器是我的 bean(单例)

public class Calculator {
private List<String> operations = new ArrayList<String>();


public void calculate(String op, double val) {
operations.add(op);
// do some calculations
}


public List<String> getAllOperations() {
return operations;
}

}

这是客户端(useCalc 被调用多次!):

public class CalculatorClient{

@Autowired
private Calculator calculator;

public void useCalc () {
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}

因此,假设 CalculatorClient useCalc 被多次调用,执行不同的操作。最终,计算器中的操作将包含该计算器上曾经完成的所有操作。

所以问题是这样的:

这是Spring的限制吗——无法在类内的方法之间有效地共享信息?如果是这样,如何在方法之间共享此类信息?

我知道有原型(prototype)bean作用域。这是这种情况下唯一的解决方案吗?顺便说一句,原型(prototype)不是这里的解决方案,因为使用原型(prototype),每次调用计算器都会实例化一个新类:

  calculator.calculate("Add",100); // New 
calculator.calculate("Div",100); // New
calculator.calculate("Diff",100); // New

由于 Singleton 是默认范围 - 开发人员不会无意中引入此类错误吗?

最佳答案

单例 Bean 的一个常见用例是将服务注入(inject)其他对象。

例如,要为对象提供连接到数据库的服务,您可以“ Autowiring ”数据库连接 bean。

您不想每次都创建一个新的数据库实例,因此单例 bean 很有意义。

通常,使用 Autowiring 的对象本身也是一个单例(在网络应用程序中, Controller 也只创建一次,您不希望为每个请求创建一个 Controller )。

aren't developers inadvertently introduce such bugs?

由于这个想法是同时处理多个请求,因此所有这些对象通常都已编码,而无需使用实例变量共享公共(public)状态。

这不是“限制”,而是最常见用例的默认值。

I know there is the prototype bean scope. Is that the only solution in this case?

这听起来像是一个很好的“解决方案”,在这种情况下将创建一个新的 bean。请注意,将原型(prototype) bean Autowiring 到单例中是没有意义的,因为在这种情况下,无论如何都只会有一个实例。

另一种更常用的可能性是 Autowiring 一个像工厂一样的单例 bean,然后在每次需要时向该工厂请求一个新对象。

工厂可以是单例,因为您不需要多个工厂,但它会在每次调用其“create”方法时返回新对象。

因此,在您的示例中,您可以执行类似的操作

@Autowired
private CalculatorFactory calcFactory;

public void useCalc () {
calculator = calcFactory.createCalculator();
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}

}

关于java - Spring Singleton 意味着类级别没有数据共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59327108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com