【问题标题】:Why is a Spring singleton-scoped bean better than a classic Singleton pattern?为什么 Spring 单例范围的 bean 比经典的单例模式更好?
【发布时间】:2013-10-12 21:08:39
【问题描述】:

我确实理解 Spring 单例范围的 bean(它们对于每个 Spring 上下文都有一个实例)和单例模式(它们对于类加载器有一个实例)之间的区别。

我注意到对于许多人来说,单例模式被认为是邪恶的(因为它们就像全局引用),而似乎没有人反对单例范围的 bean(它们也是全局可用的)。这是为什么呢?

我有一个(桌面)应用程序,我需要对某些对象进行全局访问,因为将引用传递给数十个类和方法会非常麻烦。但是我不想使用 DI 框架,因为应用程序的启动时间很重要。什么是最好的设计?

【问题讨论】:

  • 我不想使用 DI 框架,因为应用程序的启动时间很重要 您测量过这两种方法之间的差异吗?是否非常重要,我的意思是,可能 5 或 10 秒真的很重要(我只是猜测,因为这是在 Web 应用程序服务器中部署包含 200 多个类的广泛应用程序所需的时间)?
  • 您对会话范围的 bean 的看法是错误的。你真正的意思只是Spring单例。会话范围涵盖用户与 Web 服务器的一个会话,甚至在客户端桌面应用程序的上下文中没有任何意义。
  • @LuiggiMendoza 我认为 5-10 秒的启动时间对于桌面应用程序来说很重要,用户可以多次启动它......
  • @MarkoTopolnik 你说得对,我的意思是单例范围的 bean,我正在编辑问题
  • 这将取决于应用程序类型和它将做什么。如果它是像 Eclipse 这样的大型应用程序,当然会花费一些时间,但如果它是像计算器这样的应用程序,我相信在您的应用程序中添加 spring 不会产生您可能想到的开销。为它做一个基本的测试。如果它不符合您的要求,请不要使用它。

标签: java spring design-patterns dependency-injection singleton


【解决方案1】:

public static-flavored 单例不受欢迎,因为它们被硬连线到一个类中,而不是因为它们是全局的。例如,人们会告诉你他们不可能模拟测试。如果您只有少数全局对象,则不需要 Spring 来避免这种普通的 Java 单例。但是,如果您有一个需要连接在一起的大量对象图,那么如果您使用 DI 方法,您的代码将会变得更加简洁。

Spring 中有很多方便的方式来管理 bean 生命周期,特别方便的是您可以相当轻松地更改生命周期,例如从单例到原型。由于延迟决定并发执行部分代码,并且代码依赖于非线程安全对象,可能会出现这种要求。

【讨论】:

  • 我现在有 3-4 个单例,无论如何对它们进行单元测试会非常困难,因为它们周围几乎没有“业务逻辑”,它们是与 GUI 相关的类,例如我需要主JFrame 引用(作为父级)在任何可能弹出对话框的地方。所以你是说我应该继续使用单例?
  • 问问自己你是否觉得你拥有的静态单例有什么问题:它们给你带来了任何麻烦吗?如果没有,那么不要让任何笼统的“最佳实践”吓倒你:)
【解决方案2】:

注意session-scoped beans are only relevant in a WebApplicationContext.

Spring(或任何其他 IoC 容器)负责创建这些 bean,您的应用程序需要担心的只是请求它们。这就是为什么使用 DI 管理的单例更好/更容易的原因。

【讨论】:

  • 很好地实现单例模式非常容易,并且还可以访问这些对象。我不明白为什么 DI 框架管理我的单例会更好。
  • @user1954847 使用容器,您不必实现模式,只需请求实例。
  • 实现单例模式只需要很短的时间,实际上已经实现了,我只是想知道是否有更好的设计来保留启动时间。
  • @user1954847 可以通过延迟初始化实例来缩短启动时间。 DI 容器也提供了开箱即用的功能。
  • 我认为延迟初始化不会为我节省太多,因为无论如何我都需要在启动时初始化大多数对象。
【解决方案3】:

使用公共静态样式单例: 1、单元测试难。想想用构造函数注入一个模拟依赖,这根本不可能! 2. 难以在对象销毁之前或之前执行清理操作。对象一直存在到应用程序结束。

使用 Sprint Singleton 样式模式: 1. bean可以使用new关键字创建,构造函数注入很容易。 2. 由于构造函数注入,可以使用模拟对象进行单元测试。 3.可以完全控制Singleton bean的生命周期,例如Post-Construct(在对象创建后做某事)和Pre-Destroy(在对象销毁之前做某事) 4. Singleton bean可以改成非singleton bean,比如改成Prototype,非常方便。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多