Author: limpbizkit
Date: Sat Feb 28 23:16:11 2009
New Revision: 877
Modified:
wiki/Scopes.wiki
Log:
Edited wiki page through web user interface.
Modified: wiki/Scopes.wiki
==============================================================================
--- wiki/Scopes.wiki (original)
+++ wiki/Scopes.wiki Sat Feb 28 23:16:11 2009
@@ -1,16 +1,54 @@
=Scopes=
+By default, Guice returns a new instance each time it supplies a value.
This behaviour is configurable via *scopes*. Scopes allow you to reuse
instances: for the lifetime of an application (`...@singleton`), a session
(`...@sessionscoped`), or a request (`...@requestscoped`). Guice includes a
servlet extension that defines scopes for web apps. [CustomScopes Custom
scopes] can be written for other types of applications.
-==Choosing a scope==
-If the object is *stateful*, the scoping should be obvious.
Per-application is `...@singleton`, per-request is `...@requestscoped`, etc.
You
may need to write a [CustomScopes custom scope]. If the object is
*stateless* and *inexpensive to create*, scoping is unnecessary. Leave the
binding unscoped and Guice will create new instances as they're required.
-Singletons are popular in Java applications but they don't provide much
value, especially when dependency injection is involved. Although
singletons save object creation (and later garbage collection), getting a
handle to the single instance requires synchronization. Singletons are most
useful for:
- * stateful objects, such as configuration or counters
- * objects that are expensive to construct or lookup
- * objects that tie up resources, such as a database connection pool.
+==Applying Scopes==
+Guice uses annotations to identify scopes. Specify the scope for a type by
applying the scope annotation to the implementation class. As well as being
functional, this annotation also serves as documentation. For example,
`...@singleton` indicates that the class is intended to be threadsafe.
+{{{
+...@singleton
+public class InMemoryTransactionLog implements TransactionLog {
+ /* everything here should be threadsafe! */
+}
+}}}
+Scopes can also be configured in `bind` statements:
+{{{
+
bind(TransactionLog.class).to(InMemoryTransactionLog.class).in(Singleton.class);
+}}}
+And by annotating `...@provides` methods:
+{{{
+ @Provides @Singleton
+ TransactionLog provideTransactionLog() {
+ ...
+ }
+}}}
+If there's conflicting scopes on a type and in a `bind()` statement, the
`bind()` statement's scope will be used. If a type is annotated with a
scope that you don't want, bind it to `Scopes.NO_SCOPE`.
+
+In linked bindings, scopes apply to the binding source, not the binding
target. Suppose we have a class `Applebees` that implements both `Bar` and
`Grill` interfaces. These bindings allow for *two* instances of that type,
one for `Bar`s and another for `Grill`s:
+{{{
+ bind(Bar.class).to(Applebees.class).in(Singleton.class);
+ bind(Grill.class).to(Applebees.class).in(Singleton.class);
+}}}
+This is because the scopes apply to the bound type (`Bar`, `Grill`), not
the type that satisfies that binding (`Applebees`). To allow only a single
instance to be created, use a `...@singleton` annotation on the declaration
for that class. Or add another binding:
+{{{
+ bind(Applebees.class).in(Singleton.class);
+}}}
+This binding makes the other two `.in(Singleton.class)` clauses above
unnecessary.
+
+The `in()` clause accepts either a scoping annotation like
`RequestScoped.class` and also `Scope` instances like
`ServletScopes.REQUEST`:
+{{{
+ bind(UserPreferences.class)
+ .toProvider(UserPreferencesProvider.class)
+ .in(ServletScopes.REQUEST);
+}}}
+The annotation is preferred because it allows the module to be reused in
different types of applications. For example, an `...@requestscoped` object
could be scoped to the HTTP request in a web app and to the RPC when it's
in an API server.
==Eager Singletons==
-Guice can build your singletons either eagerly or lazily. Eager singletons
reveal initialization problems sooner, and ensure end-users get a
consistent, snappy experience. Lazy singletons enable a faster
edit-compile-run development cycle. Use the `Stage` enum to specify which
strategy should be used.
+Guice has special syntax to define singletons that can be constructed
eagerly:
+{{{
+
bind(TransactionLog.class).to(InMemoryTransactionLog.class).asEagerSingleton();
+}}}
+Eager singletons reveal initialization problems sooner, and ensure
end-users get a consistent, snappy experience. Lazy singletons enable a
faster edit-compile-run development cycle. Use the `Stage` enum to specify
which strategy should be used.
|| || *PRODUCTION* || *DEVELOPMENT* ||
|| .asEagerSingleton() || eager || eager ||
@@ -21,32 +59,16 @@
`*` Guice will only eagerly build singletons for the types it knows about.
These are the types mentioned in your modules, plus the transitive
dependencies of those types.
-==Scopes and Concurrency==
-Classes annotated `...@singleton` and `...@sessionscoped` *must be
threadsafe*.
Everything that's injected into these classes must also be threadsafe.
[MinimizeMutability Minimize mutability] to limit the amount of state that
requires concurrency protection.
-
-...@requestscoped objects do not need to be threadsafe. It is usually an
error for a `Singleton` or `SessionScoped` object to depend on an
`RequestScoped` one. Should you require an object in a narrower scope,
inject a `Provider` of that object.
-
+==Choosing a scope==
+If the object is *stateful*, the scoping should be obvious.
Per-application is `...@singleton`, per-request is `...@requestscoped`, etc. If
the object is *stateless* and *inexpensive to create*, scoping is
unnecessary. Leave the binding unscoped and Guice will create new instances
as they're required.
-==Applying Scopes==
-Prefer to apply scopes using an annotation on the implementing class. This
provides helpful information to the code's maintainer. For example,
`...@singleton` indicates that a class must be threadsafe.
+Singletons are popular in Java applications but they don't provide much
value, especially when dependency injection is involved. Although
singletons save object creation (and later garbage collection), getting a
handle to the single instance requires synchronization. Singletons are most
useful for:
+ * stateful objects, such as configuration or counters
+ * objects that are expensive to construct or lookup
+ * objects that tie up resources, such as a database connection pool.
-Scopes are applied to the binding source, not the binding target. For
example, suppose we have a class `Applebees` that implements both `Bar` and
`Grill` interfaces. These bindings will allow for *two* instances of that
type, one for `Bar`s and another for `Grill`s:
-{{{
- bind(Bar.class).to(Applebees.class).in(Singleton.class);
- bind(Grill.class).to(Applebees.class).in(Singleton.class);
-}}}
-This is because the scopes apply to the bound type (`Bar`, `Grill`), not
the type that satisfies that binding (`Applebees`). To allow only a single
instance of our implementation class to be created, use a `...@singleton`
annotation on the declaration for that class. Or add yet another binding:
-{{{
- bind(Applebees.class).in(Singleton.class);
-}}}
-This binding makes the other two `.in(Singleton.class)` clauses above
unnecessary.
-Prefer to bind with the scope annotation rather than the scope instance:
-{{{
- // good:
- bind(Foo.class).to(RealFoo.class).in(ServletScopes.REQUEST);
+==Scopes and Concurrency==
+Classes annotated `...@singleton` and `...@sessionscoped` *must be
threadsafe*.
Everything that's injected into these classes must also be threadsafe.
[MinimizeMutability Minimize mutability] to limit the amount of state that
requires concurrency protection.
- // better:
- bind(Foo.class).to(RealFoo.class).in(RequestScoped.class);
-}}}
-This way you can reuse the module in a non-servlets environment by
specifying a different scope to implement for `RequestScoped.class`. Even
better, use the `...@requestscoped` annotation on the implementation class.
\ No newline at end of file
+...@requestscoped objects do not need to be threadsafe. It is usually an
error for a `Singleton` or `SessionScoped` object to depend on an
`RequestScoped` one. Should you require an object in a narrower scope,
inject a `Provider` of that object.
\ No newline at end of file
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---