Google Guice and Multibinding

21 Dec, 2009
Xebia Background Header Wave

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());

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

  class SnackMachine {
    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


Where a Snack looks like this:

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)) {
            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);
     // Add a non annotated class to the bind.

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

Explore related posts