单例模式 vs 依赖注入

4
我从未使用过Java的依赖注入功能,因此我阅读了一些相关页面,但仍然不清楚单例和依赖注入之间的区别。让我们以一个基本示例为例:假设我正在构建一个小型Java应用程序,使用MVC或MVVM模式。我将从登录页面开始,请求用户名和密码。这两个信息可能稍后在应用程序中需要使用,因此我需要将它们存储在一个简单的POJO中,可从应用程序的任何视图中访问。那么我应该使用什么呢?单例模式?还是应该@Inject POJO的构造函数,并在需要时使用Injector(如Guice)获取它?谢谢帮助我理解 :)

这不是非此即彼的问题。90%(99%?)的情况下,它们是兼备的:单例与依赖注入。 - Andreas
@Andreas,你能详细说明一下吗? - c0der
说实话,我也对Andreas的回答感到有些困惑 :S - Xendar
2
作为一条提示,不要试图自己发明安全措施;你提供的例子非常不安全(你应该尽快丢弃用户的密码)。已经存在整个框架,例如Spring Security或Shiro,可以为您处理所有这些问题。在Spring Security的情况下,关于已登录用户的信息(但不包括密码)可通过开箱即用的集成方式提供给控制器和视图。 - chrylis -cautiouslyoptimistic-
1
我理解@Andreas的评论是说你经常将一个实例注入到许多地方,但恰好这是同一个实例。或者说,它是单例还是其他类型并不重要。 - Andy Turner
显示剩余2条评论
2个回答

2
简单的POJO不应该通过依赖注入来实现。因为你需要为每个请求创建一个新的实例,所以它也不应该是单例。
依赖注入应该用于完成应用程序组件/服务/存储库/bean等之间的“连线”。这有助于使您的应用程序更具模块化,封装各个组件之间的关系。而且还有更多好处。
单例是指需要应用程序中只有一个对象实例。这可以通过静态实例和getInstance方法(如单例模式)在编程上实现,或者在主类或上下文中创建一个实例来实现。在Spring中,除非另行配置,所有的bean都将是单例,因为上下文将只创建一个实例。
当您需要互相连接您的“单例”时,依赖注入会变得非常方便。
希望已经说明得足够清楚了。

1
我建议避免将依赖注入到POJO中。在这种情况下,我会将ViewModels注入一个提供/管理用户的单例类型服务。如果它们需要当前用户,则其注入的服务会提供当前相关的POJO实例。只要您的用户管理服务包装在接口中,因此可以在不破坏功能的情况下稍后替换,我认为这满足了IoC的要求。
这是我处理类似问题的方法,但我不确定这是否是最佳方法。

我确实理解这一点,并且通过专用服务访问信息肯定是正确的方式。因此,如果我们有一个服务,在需要的地方注入服务实现,这个服务将从这个 POJO(或其他什么)获取用户数据。但是,如何使这个 POJO “持久”(不是物理上的,而是在应用程序内存中保持可用性)?服务实现中的基本静态实例?还是更高级的东西? - Xendar
我不确定我完全理解这个问题,但是服务实例是一个“单例”,因为只有一个实例被注入,所以不需要静态。在单个服务实例中只有一个“当前用户”实例。由于服务是共享/单例的,所有请求将从同一服务实例传递相同的POJO。 - Joe
重新阅读我写的内容,我感觉有点愚蠢。我想我需要休息一下!尽管如此,还是谢谢你试图回答这个愚蠢的问题 :) - Xendar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接