我想知道两个绑定的作用域有什么:
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?对于没有范围,每个实例都不同吗?
对于 Gin 来说,当考虑每个客户端实例时,或者更准确地说,每个 Ginjector 实例时,单例作用域最有意义。如果您错误地通过两次GWT.create
一个实例来制作两个 Ginjector,则每个实例可能有一个"单例",因为每个 Ginjector 只能跟踪它管理的实例。
因此,每次加载应用程序时,它都会有自己的单例。如果用户在两个不同的选项卡中打开同一应用程序两次,则每个选项卡都有自己的单一实例。您可以将每个选项卡视为自己的 JVM,因为它将拥有所有类的自己的副本,并且无法在另一个窗口上进行通信或调用方法*。
对于无范围,是的,默认情况下每个实例都是不同的。当一个类型被@Inject
ed时,它将是一个新实例,但是如果你@Inject
字段的Provider
,每次调用get()
时,你都可以得到一个新的实例。这有助于轻松获取多个新注入的实例。
单例在两种主要情况下使用是有意义的
- 当实例保持需要在多次注入中通用的共享状态时 - 最常见的情况。
- 当创建实例的成本很高时 - 在服务器上,这通常作为池完成,因此创建的对象不超过 X,但客户端上昂贵的对象往往是视图,有很多小部件,通常不需要多个。
* 可以在另一个窗口上调用方法,但您需要使用浏览器的功能,通过发布消息,而不仅仅是来回传递对象。
单例仅由您创建的顶级 Ginjector 创建一次(对于大多数应用程序,您只会创建一个 Ginjector(。
每次将无作用域对象作为依赖项注入到另一个对象时,都会创建这些对象。因此,每个实例都会有所不同。实际上,如果您不打算限定绑定范围(或执行绑定器DSL可以允许您对绑定执行的任何其他操作(,则实际上不需要编写bind(SomeClass.class(。只需拥有默认构造函数或向构造函数添加@Inject,Gin 就可以创建它。
通常,当您使用Guice或Gin时,除非您有充分的理由不这样做,否则您希望将内容保留为无范围。我建议阅读有关范围的Guice文档。