Я считаю, что ваше понимание верное, но есть небольшая тонкость в отношении того, какое повторное использование будет затронуто.
Вы, вероятно, имея в виду этот текст от the Guice wiki on Scopes (курсив мой):
Предложение in()
принимает либо обзорное аннотацию, как RequestScoped.class
, а также Scope
случаях, как ServletScopes.REQUEST
:
bind(UserPreferences.class)
.toProvider(UserPreferencesProvider.class)
.in(ServletScopes.REQUEST);
примечание является предпочтительным, поскольку оно позволяет повторно использовать модуль в различных типах приложений. Например, объект @RequestScoped
может быть привязан к HTTP-запросу в веб-приложении и RPC, когда он находится на сервере API.
Даже с сервлетов конкретных областей Guice, вы можете выбрать между экземпляром Scope ServletScopes.REQUEST и @RequestScoped annotation, и выбирать между in(Scope scope)
и in(Class scopeAnnotation)
соответственно (см ScopedBindingBuilder). Почти каждая область должна иметь соответствующую аннотацию, поскольку они особенно полезны для классов и методов @Provides.
Важно осознать, что есть всегдаScope instance, что на самом деле реализует поведение обзорного (в частности, обертывания незаданного поставщика, так что он может вернуться уже возвращены экземплярами в правильных условиях). Чтобы связать аннотацию с экземпляром Scope, вам необходимо убедиться, что модуль вызывает bindScope
, который принимает класс аннотации Scope и экземпляр Scope; для сервлетов, Guice has this binding automatically installed via InternalServletModule.
@Override
protected void configure() {
bindScope(RequestScoped.class, REQUEST);
bindScope(SessionScoped.class, SESSION);
// ...
}
Так что преимущество использования in(Class scopeAnnotation)
? При привязке к экземпляру Scope вы указываете Guice точно, какой экземпляр Scope вы хотите использовать, вместо того, чтобы позволить пользователю использовать bindScope
, чтобы связать аннотацию с другим экземпляром Scope. В примере, который я выделил выше, вы можете представить, используя тот же модуль, не используя фактические расширения сервлетов Guice (кроме аннотаций), но это возможно только при привязке к классам аннотаций, а затем вызовите bindScope
самостоятельно. Если вы связываете с помощью in(Scope)
, вам нужно будет изменить эту строку или написать новый модуль.
Это особенно важно для ваших собственных экземпляров настраиваемой области и аннотации, поскольку она позволяет изменить свое поведение Scoping последовательно через приложение:
@Override public void configure() {
// BAD: To change the scope, you'll need to change three lines.
// If you don't change all three together, you'll get inconsistent behavior.
bind(A.class).to(AImpl.class).in(MyScope.INSTANCE);
bind(B.class).to(BImpl.class).in(MyScope.INSTANCE);
bindScope(AScoped.class, MyScope.INSTANCE);
}
@Override public void configure() {
// GOOD: To change the scope, you can change one line, and optionally
// extract that line to a separate Module.
bind(A.class).to(AImpl.class).in(AScoped.class);
bind(B.class).to(BImpl.class).in(AScoped.class);
bindScope(AScoped.class, MyScope.INSTANCE);
}