SeamFramework.orgCommunity Documentation

Chapter 29. Guice integration

29.1. Creating a hybrid Seam-Guice component
29.2. Configuring an injector
29.3. Using multiple injectors

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.

Note

The Guice integration is bundled in the jboss-seam-ioc library. This dependency is required for all integration techniques covered in this chapter. You will also need the Guice JAR file on the classpath.

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!