SeamFramework.orgCommunity Documentation
Google Guice is a library that provides lightweight dependency injection through type-safe
resolution. The Guice integration (part of the Seam IoC module) allows use of Guice injection
for all Seam components annotated with the @Guice
annotation. In addition
to the regular bijection that Seam performs (which becomes optional), Seam also delegates
to known Guice injectors to satisfy the dependencies of the component. Guice may be useful to
tie non-Seam parts of large or legacy applications together with Seam.
The goal is to create a hybrid Seam-Guice component. The rule for how to do this is very
simple. If you want to use Guice injection in your Seam component, annotate it with the
@Guice
annotation (after importing the type
org.jboss.seam.ioc.guice.Guice
).
@Name("myGuicyComponent")
@Guice public class MyGuicyComponent
{
@Inject MyObject myObject;
@Inject @Special MyObject mySpecialObject;
...
}
This Guice injection will happen on every method call, just like with bijection. Guice
injects based on type and binding. To satisfy the dependencies in the previous example,
you might have bound the following implementations in a Guice module, where
@Special
is an annotation you define in your application.
public class MyGuicyModule implements Module
{
public void configure(Binder binder)
{
binder.bind(MyObject.class)
.toInstance(new MyObject("regular"));
binder.bind(MyObject.class).annotatedWith(Special.class)
.toInstance(new MyObject("special"));
}
}
Great, but which Guice injector will be used to inject the dependencies? Well, you need to perform some setup first.
You tell Seam which Guice injector to use by hooking it into the injection property of the Guice initialization component in the Seam component descriptor (components.xml):
<components xmlns="http://jboss.org/schema/seam/components"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:guice="http://jboss.org/schema/seam/guice"
xsi:schemaLocation="
http://jboss.org/schema/seam/guice
http://jboss.org/schema/seam/guice-2.3.xsd
http://jboss.org/schema/seam/components
http://jboss.org/schema/seam/components-2.3.xsd">
<guice:init injector="#{myGuiceInjector}"/>
</components>
myGuiceInjector
must resolve to a Seam component that implements the
Guice Injector
interface.
Having to create an injector is boiler-plate code, though. What you really want to be able
to do is simply hook up Seam to your Guice modules. Fortunately, there is a built-in Seam
component that implements the Injector
interface to do exactly that. You
can configure it in the Seam component descriptor with this additional stanza.
<guice:injector name="myGuiceInjector">
<guice:modules>
<value>com.example.guice.GuiceModule1</value>
<value>com.example.guice.GuiceModule2</value>
</guice:modules>
</guice:injector>
Of course you can also use an injector that is already used in other, possibly non-Seam part of you application. That's one of the main motivations for creating this integration. Since the injector is defined with EL expression, you can obtain it in whatever way you like. For instance, you may use the Seam factory component pattern to provide injector.
@Name("myGuiceInjectorFactory")
public InjectorFactory
{
@Factory(name = "myGuiceInjector", scope = APPLICATION, create = true)
public Injector getInjector()
{
// Your code that returns injector
}
}
By default, an injector configured in the Seam component descriptor is used. If you really
need to use multiple injectors (AFAIK, you should use multiple modules instead), you can
specify different injector for every Seam component in the @Guice
annotation.
@Name("myGuicyComponent")
@Guice("myGuiceInjector")
public class MyGuicyComponent
{
@Inject MyObject myObject;
...
}
That's all there is to it! Check out the guice example in the Seam distribution to see the Seam Guice integration in action!