3

我想知道两个绑定后的范围有哪些:

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

bind(PermissionManager.class);

我已经阅读了 JavaDocs,它们如下。对于单身人士:

/**
* Apply this to implementation classes when you want only one instance
* (per {@link Injector}) to be reused for all injections for that binding.
*
* @author crazybob@google.com (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 是单例吗?没有范围,每个实例都不同吗?

4

2 回答 2

3

实际上,对于 Gin,Singleton 范围在考虑每个客户端实例时最有意义,或者更准确地说,每个 Ginjector 实例。如果你错误地通过两次调用GWT.create一个实例来创建两个 Ginjector,那么每个实例可能会有一个“单例”,因为每个 Ginjector 只能跟踪它管理的实例。

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

对于没有范围,是的,默认情况下每个实例都是不同的。当一个类型被@Inject编辑时,它将是一个新的实例,但如果你@InjectProvider一个字段,每次你调用get()你都可以获得一个新的实例。这有助于轻松获取几个新注入的实例。

单例在两种主要情况下使用是有意义的

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

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

于 2012-02-25T21:55:17.337 回答
2

单例仅由您创建的顶级 Ginjector 创建一次(对于大多数应用程序,您只创建一个 Ginjector)。

每次将非作用域对象作为依赖项注入另一个对象时,都会创建非作用域对象。所以每个实例都会不同。如果您不打算对它进行限定(或执行 binder DSL 可以让您对绑定执行的任何其他操作),您实际上不需要编写 bind(SomeClass.class) 。只需使用默认构造函数或将 @Inject 添加到构造函数即可让 Gin 能够创建它。

通常,当您使用 Guice 或 Gin 时,除非您有充分的理由不这样做,否则您希望将其保留为无范围。我建议阅读有关范围的 Guice 文档

于 2012-02-24T21:46:52.893 回答