Author: limpbizkit
Date: Sun Feb 22 23:16:10 2009
New Revision: 864
Modified:
wiki/All.wiki
Log:
Modified: wiki/All.wiki
==============================================================================
--- wiki/All.wiki (original)
+++ wiki/All.wiki Sun Feb 22 23:16:10 2009
@@ -1,6 +1,8 @@
=Java on Guice=
Guice 2.0 User's Guide
+
Guice \(pronounced "juice"\) is an ultra-lightweight, next-generation
dependency injection container for Java 5 and later.
+
<wiki:toc max_depth="1" />
=Motivation=
Wiring everything together is a tedious part of application development.
There are several approaches to connect data, service, and presentation
classes to one another. To contrast these approaches, we'll write the
billing code for a pizza ordering website:
@@ -235,7 +237,8 @@
BillingService billingService =
injector.getInstance(BillingService.class);
...
}
-}}}=Best Practices=
+}}}
+=Best Practices=
=Minimize mutability=
Wherever possible, use constructor injection to create immutable objects.
Immutable objects are simple, shareable, and can be composed. Follow this
pattern to define your injectable types:
{{{
@@ -264,7 +267,8 @@
*Method injection* is most useful when you need to initialize an instance
that is not constructed by Guice. Extensions like AssistedInject and
Multibinder use method injection to initialize bound objects.
-*Field injection* has the most compact syntax, so it shows up frequently
on slides and in examples. It is neither encapsulated nor testable. Never
inject [http://code.google.com/p/google-guice/issues/detail?id=245 final
fields]; the JVM doesn't guarantee that the injected value will be visible
to all threads.=Inject only direct dependencies=
+*Field injection* has the most compact syntax, so it shows up frequently
on slides and in examples. It is neither encapsulated nor testable. Never
inject [http://code.google.com/p/google-guice/issues/detail?id=245 final
fields]; the JVM doesn't guarantee that the injected value will be visible
to all threads.
+=Inject only direct dependencies=
Avoid injecting an object only as a means to get at another object. For
example, don't inject a `Customer` as a means to get at an `Account`:
{{{
public class ShowBudgets {
@@ -287,12 +291,14 @@
return customer.getPurchasingAccount();
}
}}}
+
=Avoid static state=
Static state and testability are enemies. Your tests should be fast and
free of side-effects. But non-constant values held by static fields are a
pain to manage. It's tricky to reliably tear down static singletons that
are mocked by tests, and this interferes with other tests.
`requestStaticInjection()` is a *crutch*. Guice includes this API to ease
migration from a statically-configured application to a dependency-injected
one. New applications developed with Guice should not use this API.
Although *static state* is bad, there's nothing wrong with the static
*keyword*. Static classes are okay (preferred even!) and for pure functions
(sorting, math, etc.), static is just fine.
+
=Use @Nullable=
To eliminate `NullPointerExceptions` in your codebase, you must be
disciplined about null references. We've been successful at this by
following and enforcing a simple rule:
_Every parameter is non-null unless explicitly specified._
@@ -311,6 +317,7 @@
}
}}}
*Guice forbids null by default.* It will refuse to inject `null`, failing
with a `ProvisionException` instead. If `null` is permissible by your
class, you can annotate the field or parameter with `...@nullable`. Guice
recognizes any `...@nullable` annotation, like
[http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Nullable.html
com.google.common.base.Nullable] or
[http://code.google.com/p/jsr-305/source/browse/trunk/ri/src/main/java/javax/annotation/Nullable.java?r=24
javax.annotation.Nullable].
+
=Modules should be fast and side-effect free=
Rather than using an external XML file for configuration, Guice modules
are written using regular Java code. Java is familiar, works with your IDE,
and survives refactoring.
@@ -352,13 +359,15 @@
webserver.start();
addShutdownHook(webserver);
}
-}}}=Be careful about I/O in Providers=
+}}}
+=Be careful about I/O in Providers=
The `Provider` interface is convenient for the caller, but it lacks
semantics:
* *Provider doesn't declare checked exceptions.* If you're writing code
that needs to recover from specific types of failures, you can't catch
`TransactionRolledbackException`. `ProvisionException` allows you to
recover from general provision failures, and you can
[http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/ProvisionException.html#getErrorMessages()
iterate its causes], but you can't specify what those causes may be.
* *Provider doesn't support a timeout.*
* *Provider doesn't define a retry-strategy.* When a value is
unavailable, calling `get()` multiple times may cause multiple failed
provisions.
-ThrowingProviders is a Guice extension that implements an
exception-throwing provider. It allows failures to be scoped, so a failed
lookup only happens once per request or session.=Avoid conditional logic in
modules=
+ThrowingProviders is a Guice extension that implements an
exception-throwing provider. It allows failures to be scoped, so a failed
lookup only happens once per request or session.
+=Avoid conditional logic in modules=
It’s tempting to create modules that have moving parts and can be
configured to operate differently for different environments:
{{{
public class FooModule {
@@ -384,7 +393,8 @@
}}}
Conditional logic in itself isn't too bad. But problems arise when
configurations are untested. In this example, the`InMemoryFooService` is
used for development and `RemoteFooService` is used in production. But
without testing this specific case, it's impossible to be sure that
`RemoteFooService` works in the integrated application.
-To overcome this, *minimize the number of distinct configurations* in your
applications. If you split production and development into distinct
modules, it is easier to be sure that the entire production codepath is
tested. In this case, we split `FooModule` into `RemoteFooModule` and
`InMemoryFooModule`. This also prevents production classes from having a
compile-time dependency on test code.=Scopes=
+To overcome this, *minimize the number of distinct configurations* in your
applications. If you split production and development into distinct
modules, it is easier to be sure that the entire production codepath is
tested. In this case, we split `FooModule` into `RemoteFooModule` and
`InMemoryFooModule`. This also prevents production classes from having a
compile-time dependency on test code.
+=Scopes=
==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.
@@ -435,7 +445,8 @@
// 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.=Web And Servlets=
+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.
+=Web And Servlets=
#summary Guice Servlet Extensions
= Introduction =
@@ -469,7 +480,8 @@
</filter-mapping>
}}}
-This tells the Servlet Container to re-route all requests through
`GuiceFilter`. The nice thing about this is that any servlets or JSPs you
already have will continue to function as normal, and you can migrate them
to Guice Servlet at your own pace.#summary Using Guice Servlet and Binding
Language
+This tells the Servlet Container to re-route all requests through
`GuiceFilter`. The nice thing about this is that any servlets or JSPs you
already have will continue to function as normal, and you can migrate them
to Guice Servlet at your own pace.
+#summary Using Guice Servlet and Binding Language
= Installing a Servlet Module =
@@ -572,7 +584,8 @@
serve("*.html", "/my/*").with(MyServlet.class);
}}}
-This way you can map several URI patterns to the same servlet. A similar
syntax is also available for filter mappings.#summary Advanced topics:
regex mapping, init params, etc.
+This way you can map several URI patterns to the same servlet. A similar
syntax is also available for filter mappings.
+#summary Advanced topics: regex mapping, init params, etc.
= Regular Expressions =
@@ -613,7 +626,8 @@
bind(Filter.class).annotatedWith(Fave.class).to(MyFilterImpl.class);
}}}
-See the [UserGuide User's Guide] for more information on binding and
annotations.=Extensions=
+See the [UserGuide User's Guide] for more information on binding and
annotations.
+=Extensions=
#summary Guice's SPI for authors of tools, extensions and plugins
The
[http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/spi/package-summary.html
service provider interface] exposes Guice's internal models to aid in the
development in tools, extensions, and plugins.
@@ -643,7 +657,8 @@
});
}
}
-}}}#summary an easier way to help the Guice Injector build objects
+}}}
+#summary an easier way to help the Guice Injector build objects
=!AssistedInject=
==Factories by Hand==
@@ -711,12 +726,14 @@
With `FactoryProvider`, it's easier to create classes that need extra
arguments at construction time:
# Annotate the constructor and assisted parameters on the implementation
class (such as `RealPayment`)
# Create a factory interface with a `create()` method that takes only
the assisted parameters. Make sure they're in the same order as in the
constructor
- # Bind that factory to a provider created by `FactoryProvider`.#summary
Overview of Multibinder and MapBinder extensions
+ # Bind that factory to a provider created by `FactoryProvider`.
+#summary Overview of Multibinder and MapBinder extensions
=Multibindings=
[http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/multibindings/Multibinder.html
Multibinder] and
[http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/multibindings/MapBinder.html
MapBinder] are intended for plugin-type architectures, where you've got
several modules contributing Servlets, Actions, Filters, Components or even
just names.
==Limitations==
-When you use !PrivateModules with multibindings, all of the elements must
be bound in the same environment. You cannot create collections whose
elements span private modules. Otherwise injector creation will
fail.=Custom Scopes=
+When you use !PrivateModules with multibindings, all of the elements must
be bound in the same environment. You cannot create collections whose
elements span private modules. Otherwise injector creation will fail.
+=Custom Scopes=
It is generally recommended that users *do not* write their own custom
scopes — the built-in scopes should be sufficient for most applications. If
you're writing a web application, the `ServletModule` provides simple, well
tested scope implementations for HTTP requests and HTTP sessions.
Creating custom scopes is a multistep process:
@@ -894,7 +911,8 @@
scope.exit();
}
}
-}}}#summary Using Guice in an OSGi container
+}}}
+#summary Using Guice in an OSGi container
=OSGi=
[http://www.osgi.org/ OSGi] is a dynamic module system used in many
projects including [http://www.eclipse.org/ Eclipse] and
[https://glassfish.dev.java.net/ GlassFish]. A module in OSGi is known as a
bundle - basically a JAR with additional metadata. This metadata describes
the bundle's identity, what packages it needs, and what it provides. Guice
added OSGi metadata in its second release, which means you can now install
it as a bundle on any modern OSGi container.
@@ -925,7 +943,8 @@
{{{
"-Dorg.osgi.framework.bootdelegation=org.aopalliance.*,com.google.inject.*"
}}}
-You can still dynamically unload and reload bundles when using
bootdelegation with Guice, but you would need to restart the JVM to replace
the Guice bundle itself. This is much less likely to happen compared to
upgrading client bundles, and it's usually fine to do a full shutdown when
a key production service is upgraded. This also avoids potential problems
like serialization-compatibility for HTTP session objects.=Struts 2
Integration=
+You can still dynamically unload and reload bundles when using
bootdelegation with Guice, but you would need to restart the JVM to replace
the Guice bundle itself. This is much less likely to happen compared to
upgrading client bundles, and it's usually fine to do a full shutdown when
a key production service is upgraded. This also avoids potential problems
like serialization-compatibility for HTTP session objects.
+=Struts 2 Integration=
To install the Guice Struts 2 plugin with Struts 2.0.6 or later, simply
include `guice-struts2-plugin-1.0.jar` in your web application's classpath
and select Guice as your ObjectFactory implementation in your `struts.xml`
file:
{{{
<constant name="struts.objectFactory" value="guice" />
@@ -988,7 +1007,8 @@
</body>
</html>
}}}
-We actually made this example more complicated than necessary in an
attempt to illustrate more concepts. In reality, we could have done away
with the separate `Counter` object and applied `...@sessionscoped` to our
action directly.#summary throwing providers extension tutorial
+We actually made this example more complicated than necessary in an
attempt to illustrate more concepts. In reality, we could have done away
with the separate `Counter` object and applied `...@sessionscoped` to our
action directly.
+#summary throwing providers extension tutorial
= Throwing Providers =
@@ -1057,7 +1077,8 @@
}
}}}
==Notes on Scoping==
-Scopes work the same way they do with Providers. Each time get() is
called, the returned object will be scoped appropriately. Exceptions are
also scoped. For example, when worldNewsFeedProvider.get() throws an
exception, the same exception instance will be thrown for all callers
within the scope.#summary Using grapher to visualize Guice applications
+Scopes work the same way they do with Providers. Each time get() is
called, the returned object will be scoped appropriately. Exceptions are
also scoped. For example, when worldNewsFeedProvider.get() throws an
exception, the same exception instance will be thrown for all callers
within the scope.
+#summary Using grapher to visualize Guice applications
= Grapher =
When you've written a sophisticated application, Guice's rich
introspection API can describe the object graph in detail. The built-in
grapher extension exposes this data as an easily understandable
visualization. It can show the bindings and dependencies from several
classes in a complex application in a unified diagram.
@@ -1152,7 +1173,8 @@
Other behavior:
* If an injection point requests a `Provider<Foo>`, the grapher will
elide the `Provider` and just show a dependency to `Foo`.
- * The grapher will use an instance's `toString()` method to render its
title if it has overridden `Object`'s default implementation.#summary 3rd
party Guice addons
+ * The grapher will use an instance's `toString()` method to render its
title if it has overridden `Object`'s default implementation.
+#summary 3rd party Guice addons
=Third Party Modules=
==Infrastructure==
@@ -1188,7 +1210,8 @@
* *[http://code.google.com/p/groovy-guice/ Groovy-Guice]* - Groovy
* *[http://ninject.org/ Ninject]* - .NET
* *[http://code.google.com/p/snake-guice/ Snake Guice]* - Python
- * *[http://code.google.com/p/smartypants-ioc/ Smartypants-IOC]* -
Flex=Development=
+ * *[http://code.google.com/p/smartypants-ioc/ Smartypants-IOC]* - Flex
+=Development=
#summary Significant changes in Guice 2.0
#labels Featured
=Changes in Guice 2=
@@ -1319,7 +1342,8 @@
Guice 2.0 throws an exception if the binding cannot be resolved. The old
version used to return null. To get the old behaviour, use
`injector.getBindings().get(key)`.
===SPI Changes===
-!SourceProviders have been replaced with `Binder.withSource` and
`Binder.skipSources`. These new methods are easier to call and test. They
don't require static initialization or static dependencies.#summary
Building Guice without AOP support
+!SourceProviders have been replaced with `Binder.withSource` and
`Binder.skipSources`. These new methods are easier to call and test. They
don't require static initialization or static dependencies.
+#summary Building Guice without AOP support
= Optional AOP =
Guice 1.0 was available in a single version that included AOP.
@@ -1349,4 +1373,4 @@
ant no_aop
cd build/no_aop/
ant dist
-}}}
\ 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
-~----------~----~----~----~------~----~------~--~---