根据Guice wiki page,对于无状态对象,未编码绑定优先于Singleton。
我不同意该陈述,因为:
有人可以解释为什么默认范围是首选的无状态对象的单例范围?
答案 0 :(得分:1)
对于未编码对象而不是单例对象的偏好有一个重要而重要的原因:单例对象永远不会被垃圾收集,它们所持有的对象的整个传递树也不能被引用。< / em>它们的结构需要同步(以防止在创建过程中出现竞争条件),然后它们会在注射器的整个生命周期内保留在内存中。
这尤其是一个问题,因为在生产环境中,all Guice singletons are eager无论是否绑定asEagerSingleton
。这意味着在生产中,单个树的内存承诺在创建注入器时开始,并且通常持续到应用程序关闭。
单独使用Singletons可能会导致启动速度变慢,内存需求量大于明智地选择单例。
当然,如果对象及其依赖项都是无状态的,那么每个对象的内存占用量都很小。但是,如果您的单例依赖于依赖于依赖于数据库的对象的对象,则在启动时将需要该数据库及其内存,并且永远不会释放。
injector ___________________TIME_________________________\
creation /
|---------------------SINGLETON-------------------------->
|----------REQUEST A------------| |---REQUEST B----->
|-UNSCOPED C-| |-UNSCOPED D-| |-UNSCOPED E-|
范围大致跟踪对象的生命周期,目标是避免将较窄范围的对象注入更宽范围的对象(例如,保留未绑定的对象C,这可能是与请求A相关但不是请求B)。这样做将是范围扩大注入。
当您提到未穿眼镜的物体时,请将它们视为短暂的或一次性的,并尽可能缩小范围。这使得无状态对象变得特别容易,因为你拥有的实例并不重要。
这些未编组对象也可以在不使用提供程序的情况下自由地在图中注入任何对象,前提是未绑定对象与您选择的任何其他依赖项相比总是具有更短的生命周期。相比之下,单身人士必须使用提供者来处理所有非单身依赖关系,因为它绝对会比它所依赖的任何非单身人士更长久。
这应该在您需要提供商时明确说明,正如您在上面的#1和#4中所提到的那样。
总之,我只能将你引回the section you linked:除非你有充分的理由(州,昂贵的建筑或资源管理),否则你应该让你的注射器不受约束。