2012-02-24 247 views
3

我不知道什么范围如下因素两个绑定有:GIN绑定的范围是什么?

bind(PermissionManager.class).in(Singleton.class); 

bind(PermissionManager.class); 

我已阅读JavaDoc中,他们表现如下。对于辛格尔顿:

/** 
* Apply this to implementation classes when you want only one instance 
* (per {@link Injector}) to be reused for all injections for that binding. 
* 
* @author [email protected] (Bob Lee) 
*/ 

对于无范围:

/** 
* No scope; the same as not applying any scope at all. Each time the 
* Injector obtains an instance of an object with "no scope", it injects this 
* instance then immediately forgets it. When the next request for the same 
* binding arrives it will need to obtain the instance over again. 
* 
* <p>This exists only in case a class has been annotated with a scope 
* annotation such as {@link Singleton @Singleton}, and you need to override 
* this to "no scope" in your binding. 
* 
* @since 2.0 
*/ 

这是什么意思在实用性方面?每个客户端或每个JVM都是单身人士吗?对于没有范围,每个实例都不同?

回答

3

实际上,对于杜松子酒,Singleton作用域在每个客户端实例或更准确地说,每个Ginjector实例考虑时最有意义。如果你错误地让一个实例创建两个Ginjectors两次,那么每个实例可能会有一个“singleton”,因为每个Ginjector只能跟踪它所管理的实例。

因此,每次加载应用程序时,它都会有自己的单例。如果用户在两个不同的选项卡中打开两次相同的应用程序,则每个应用程序都有自己的单例。您可以将每个选项卡都视为自己的JVM,因为它将拥有自己的所有类的副本,并且无法在其他窗口上进行通信或调用方法*。

对于没有范围,是的,默认情况下,每个实例是不同的。当一个类型为@Inject ed时,它将成为一个新的实例,但如果您的字段为@Inject a Provider,则每次调用get()时,都可以获得一个新实例。这对于轻松获得几个新注入的实例可能会有所帮助。

单身有意义的两种主要情况

  • 当实例保存共享一个需要跨越许多常见的注射用状态 - 最常见的情况。
  • 当实例创建成本很高时 - 在服务器上这通常是作为一个池来完成的,因此不会创建超过X个对象,但客户端上的昂贵对象往往是视图,有很多小部件,并且通常不止一个是不需要的。

*可以在另一个窗口调用方法,但是您需要使用浏览器的功能来发布消息,而不是仅仅来回传递对象。

+0

感谢您的解释。所以在我的情况下,我有一个'PermissionManager',每个用户都拥有权限。它们对于与用户会话相关的所有注入应该是通用的(我不关心多个浏览器选项卡)。根据我的理解,“@ Singleton”是我需要的,对吧? – 2012-02-26 23:05:06

+0

如果它本身持有状态(而不是从其他实例读取),那么很可能。您可能会发现使用'Provider'接口在实例准备就绪之前将其设置为null是方便的,并且将该提供程序作为单例绑定,但允许任何读取perms的请求都要求该提供程序使用'PermissionManager'。 (如果这是在服务器上,你可以使用@SessionScoped来替代,而Guice会想出如何保持会话特定的。)有多种方法可以正确执行此操作,具体取决于具体情况,以及何时数据,它的有效时间。 – 2012-02-27 02:23:11

+0

哦,它在服务器上,不能相信我忘了提及这一点。看起来像'@ SessionScoped'就是我需要的。 – 2012-02-27 17:32:32

2

单件只由您创建的最高级别的注射器创建(对于大多数应用程序,您只创建一个注射器)。

每次将其注入为另一个对象的依赖项时,都会创建未对比的对象。所以每个实例都会有所不同。如果您不打算对其进行限定(或者执行绑定程序DSL允许您执行绑定的任何其他操作),则实际上不需要编写绑定(SomeClass.class)。只需使用默认构造函数或向构造函数添加@Inject就可以让Gin创建它。

一般来说,当您使用Guice或杜松子酒时,您希望让事情不受影响,除非您有充分的理由不这样做。我会推荐阅读Guice documentation about scopes