【问题标题】:How much overhead does prototype scope cause?原型范围会导致多少开销?
【发布时间】:2020-07-31 14:44:52
【问题描述】:

我的理解是,原型范围的 Java bean 类在每次被请求时都会被实例化,而单例范围的 Java bean 会在应用程序启动时被实例化一次。

我的问题是:使用原型作用域会导致多少开销?

  • Spring 框架是否尝试回收原型范围的对象以减少重复实例化带来的开销?
  • 原型作用域引起的开销是否足以保证我尽可能多地使我的 Java bean 类无状态,以便我可以对它们应用单例作用域?

【问题讨论】:

  • 我无法回答您的问题,但我从不使用 Prototype 范围,因为我所有的 bean 都是无状态的。在您的案例中使用 Prototype 范围的原因是什么?
  • 与每次创建新对象的开销相同,
  • 为什么是原型范围?为什么要自己承担清理 bean 的开销?
  • @SimonMartinelli 我的 bean 是有状态的(它们包含实例变量),它们可能同时服务于多个请求。我担心如果我的 bean 没有被限定为原型,就会出现线程安全问题。

标签: java spring spring-boot spring-mvc


【解决方案1】:

您不应该考虑原型和单例范围之间的开销,而应该只考虑它们的使用方式。如果它们是在应用程序的整个生命周期中都存在的无状态对象,则正确的范围是单例。许多 bean 存在于该范围内,例如控制器、服务中的 bean 或持久层。大多数与 Spring Security 框架相关的 bean 也是无状态的,并且存在于单例范围内。

如果您想为特定处理创建一个全新的 bean,然后在使用它时将其丢弃,那么它是原型范围的用例。由于我主要将 spring 用于 Web 应用程序,因此我很少使用原型作用域 bean,但使用了具有紧密用例的请求作用域 bean:它们是为 HTTP 请求处理而创建的。唯一需要注意的是,如果必须在单例 bean 中注入原型或请求范围 bean,则必须使用允许连接到当前原型 bean 的代理(可能在线程存储),而不是单例时创建的 bean。

【讨论】:

    【解决方案2】:

    使用原型作用域与使用“new”实例化相同,只是新对象将由 Spring 管理。 Spring 将能够应用方面、注入依赖项等。还会产生为包装对象而创建的代理类的开销。

    Spring 不会尝试重用实例。

    如果您不想在引用 bean 时创建新实例,那么您不应该使用原型。您的解决方案将需要独立的实例,可能是由于并发性,或者它将允许单例。对象使用的内存不太可能成为您使用什么范围的决定因素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-19
      • 2016-02-05
      • 1970-01-01
      • 2010-10-07
      • 2017-08-16
      • 2021-11-30
      • 2013-02-09
      • 2010-12-16
      相关资源
      最近更新 更多