• Home
  • RSS Feed
  • Log in

Mischa Dasberg

Google Guice and Multibinding
Posted by Mischa Dasberg around lunchtime: December 21st, 2009

Last week I started migrating an application that used Spring for DI to Google Guice when I stumbled on multibinding.

Since Google Guice 2.0 we can use Multibinding which allows us to bind multiple objects to a collection.
But the one thing I missed in the current release is the ability to bind objects with a specific annotation. So I thought, why not build it myself :)


So lets use the Multibinder example written in the Javadoc of Multibinder.

public class SnacksModule extends AbstractModule {
    protected void configure() {
     Multibinder multibinder = Multibinder.newSetBinder(binder(), ISnack.class);
      multibinder.addBinding().toInstance(new Twix());
      multibinder.addBinding().toProvider(SnickersProvider.class);
      multibinder.addBinding().to(Skittles.class);
    }
  }

With this binding, a Set<ISnack> can now be injected:

  class SnackMachine {
    @Inject
    public SnackMachine(Set snacks) { ... }
  }

This is nice if you have a couple of Snacks, but if you have many and you want your
module clean and simple, you probably want something like this

 multibind(ISnack.class).toAnnotatedClasses(Snack.class);

Where a Snack looks like this:

@Snack
public class Snickers implements ISnack { ... }

To make this possible, I created the following Module:

public abstract class AbstractMultibindModule extends AbstractModule {

    public  AdvancedMultibinder multibind(Class clazz) {
        return new AdvancedMultibinder(clazz);
    }

    public class AdvancedMultibinder {
        private Multibinder multibinder;
        private Class clazz;

        private AdvancedMultibinder(Class clazz) {
            this.clazz = clazz;
            multibinder = Multibinder.newSetBinder(binder(), clazz);
        }

        public Multibinder toAnnotatedClasses(Class bindingAnnotation) {
            return toAnnotatedClasses(bindingAnnotation, clazz.getPackage().getName());
        }

        public Multibinder toAnnotatedClasses(Class bindingAnnotation, String basePackageName) {
            for (Class clazz : AnnotationUtil.getAnnotatedClasses(bindingAnnotation, basePackageName)) {
                multibinder.addBinding().to(clazz);
            }
            return multibinder;
        }

        public LinkedBindingBuilder addBinding() {
            return multibinder.addBinding();
        }
    }
}

As you can see the multibind method returns an AdvancedMultibinder. We cannot extend Multibinder because it has a private Constructor, so instead I use the multibinder internally and call methods on it to add bindings.

The AdvancedMultibinder has a method toAnnotatedClasses, which takes the annotation class as a parameter and adds a binding for each annotated class.

Now we can do the following.

     AdvancedMultibinder multibinder = multibind(ISnack.class);
     multibinder.toAnnotatedClasses(Snack.class);

     // Add a non annotated class to the bind.
     multibinder.addBinding().to(Skittles.class);

     bind(Machine.class).to(SnackMachine.class);

I have attached the example project here so you can look into the code yourself.

Share

Filed under Java | 7 Comments »



7 Responses to “Google Guice and Multibinding”



    Jesse Wilson Says:
    Posted at: December 21, 2009 at 6:31 pm

    Neato!

    Reply


    niels Says:
    Posted at: December 24, 2009 at 10:19 am

    >> @Snack
    >> public class Snickers implements ISnack

    I don’t know anything about Guice, but it seems rather redundant. Isn’t it possible to specify something similar to:
    AdvancedMultibinder multibinder = multibind(ISnack.class);
    multibinder.toImplementingClasses(ISnack.class);

    or even:
    AdvancedMultibinder multibinder = multibind(ISnack.class);
    multibinder.bindAllImplementingClasses();

    Niels

    Reply


    Sakuraba Says:
    Posted at: December 24, 2009 at 10:29 am

    I wish those were available in GIN. Could definetly use those!

    Reply


    iwein Says:
    Posted at: December 26, 2009 at 9:25 am

    That’s pretty nice. I have to agree with niels though, the parametrization of the collection doesn’t stack up against the redundancy of implementing the interface and annotate. But that’s easily fixed I think.

    Reply


    Mischa Dasberg Says:
    Posted at: December 26, 2009 at 1:16 pm

    @niels and Iwein,

    As you can see in the example I bind all Snacks with the Snack annotation. (maybe I should have called the annotation DefaultSnack)

    multibinder.toAnnotatedClasses(Snack.class);
    // Add a non annotated class to the bind.
    multibinder.addBinding().to(Skittles.class);

    And I add Skittles to my personal snackmachine which doesn’t have the annotation.
    The downside of the toImplementingClasses would be that I can’t exclude any implementing class.

    Reply


    Erik Jan Says:
    Posted at: January 13, 2010 at 9:33 am

    Great blog, I’ve one question why would you want to migrate from spring to guice?

    Reply


    Mischa Dasberg Says:
    Posted at: January 13, 2010 at 3:00 pm

    @Erik, why not? Both Spring and Guice work great, but Guice makes your code cleaner and the setup is easier and more readable.

    Reply


Leave a Reply

Click here to cancel reply.


Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India
  • XebiCon 2012

Categories

  • Java (312)
  • Agile (192)
  • General (141)
  • Scrum (70)
  • Testing (65)
  • Architecture (65)
  • Performance (47)
  • Middleware (59)
    • Deployment (40)
  • Xebia Labs (41)
  • SOA (31)
  • Project Management (31)
  • Podcast (31)
  • Tools (28)
  • Uncategorized (24)
  • lean architecture (20)
  • Quality Assurance (19)
  • Articles (15)
  • Requirements Management (14)
  • Virtualization (21)

Tag Cloud

    Ajax Java Scala Flex XML Maven Concurrency Control SOA Oracle Spring Moving to India Grails Frameworks agile architectuur Javascript lean architectuur product owner Lean JPA Eclipse Hibernate TDD JPA implementation patterns ACT Xebia Scrum Architecture Groovy Agile lean architecture

Archives

  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
Avatars by Sterling Adventures