Rich Newman

May 22, 2010

A Comparison of Some Dependency Injection Frameworks: Part 6 Guice (Java) Continued

Introduction

Part 5 of this series of articles started examining Guice as a dependency injection framework.  This article completes that, and makes some general comments on the Guice framework.

The code for this article is available (it’s the same code as in part 5).

Testing Guice (Continued)

Tests 4 and 5:  Creation of an object with singleton scope, creation of an object with prototype scope

As before we run tests 4 and 5 by making the MovieLister class from test 2 have singleton scope, and the MovieLister from test 3 have prototype scope.  We do this in the private module configuration classes set up in test 3.

The syntax for specifying that a class is a singleton is straightforward, and can be seen in the SimpleMovieListerPrivateModule class:

            bind(MovieLister.class)
            .annotatedWith(Simple.class)
            .to(MovieLister.class)
            .in(Singleton.class);

Note that we’ve just added the simple syntax ‘.in(Singleton.class)’ to our binding to specify the singleton.

The default scope is prototype here, so in the ColonDelimitedMovieListerPrivate module class we don’t need to do anything special.  So if we make the simple singleton change above the tests pass.

Test 6: Use of a factory class and method to create a dependent object.

Test 6 is intended to test our ability to use code (in a different) class to generate the object we require when we request it from the container.  Here we want to return a MovieLister from a factory class.

In Guice you can do this with a ‘provider’: the provider is the equivalent of the factory from earlier Spring examples.  For our test we write a class that implements the Provider<MovieLister> interface.  As you can see this interface has a ‘get’ method that returns a MovieLister, which is our factory method.

We need to bind this so that when we request a MovieLister our factory method gets called.  To do this we put the binding code below into our main module (configuration) class:

            bind(MovieLister.class)
            .annotatedWith(Complex.class)
            .toProvider(ComplexMovieListerFactory.class);

Note that we need an annotation because we already have other configurations that return type MovieLister from the container.  Now if we request an object from the container with the MovieLister/Complex key as below Guice will run the get method on our ComplexMovieListerFactory and return the result, which is what we want:

            MovieLister complexLister = guiceInjector.getInstance(Key.get(MovieLister.class, Complex.class));
            Movie[] tarkovskyMovies = complexLister.moviesDirectedBy("Andrei Tarkovsky");
            for(Movie movie : tarkovskyMovies){
                  System.out.println(movie.toString());

Whilst this isn’t particularly complex it is quite a different approach to the configuration approaches we’ve already seen in Guice: now we’re implementing an interface to get Guice to configure an object.

Test 7: Injection of the container itself (so it can be used to retrieve objects).

The code for this again is in the ComplexMovieListerFactory class.  Here Guice is actually simpler than Spring, since it doesn’t require implementation of a specific interface to inject the container.  You simply use the usual syntax in your class: here we write a constructor with the appropriate signature to take the container, and mark that constructor with the @Inject attribute:

public class ComplexMovieListerFactory implements Provider<MovieLister> {
      
      private Injector injector;
      
      @Inject
      public ComplexMovieListerFactory(Injector injector) {
            this.injector = injector;
      }
...

The rest of the ComplexMovieListerFactory class is fairly self-explanatory.  One thing to note is that (as far as I can see) the Guice container has no equivalent of Spring’s ‘getBeansOfType’ method, so we’re having to retrieve the Movie objects individually from the container.  My feeling is this is not really important as this is a little unrealistic: in practice: we’d be unlikely to want to retrieve instances of all objects in the container of a given type.

Comments on Guice

Guice is directly trying to deal with some of the problems with XML configuration I outlined in the first article in this series.  In particular it’s trying to remove those incomprehensible runtime errors you can get if  you your XML configuration is wrong.

For simple injection scenarios it does seem like a step forward.  However, I find Guice quite hard to like (and when I started this analysis I really wanted to like it).

  • There are several different ways of configuring an object.  As you can see from the length of this article and part 5, this can get quite confusing and difficult.  You have to learn and understand the different scenarios to be able to use the framework.
  • The different configuration methods are used in different circumstances depending on the complexity of the configuration scenario.  As we have seen, this can include changing the configuration for an existing object when a new object of the same type needs to be configured.  Again you have to understand and be able to handle this. 
  • For any moderately complex injection scenario you are having to change the code of your classes by annotating them.  This effectively means we have construction logic back in our code classes, albeit in a limited way and in the form of metadata rather than actual code.
  • The code in the configuration classes isn’t particularly intuitive.  In particular the use of private modules for the solution to the so-called ‘robot legs’ problem leads to quite complex code.

Overall my feeling is that Guice does address some of the issues with XML configuration that we see in frameworks like Spring.  However it then introduces a number of issues of its own.  Obviously I have tested with some reasonably advanced scenarios here.  Some of these may not need to be used that frequently in real production code. I haven’t personally used Guice on any real life project.  But on the basis of this analysis I think I would be reluctant to attempt to do so.

Conclusion

Guice was the most disappointing framework I looked at.  Its design goals are explicitly to solve some of the problems with XML configuration discussed in part 1 of this series of articles.  However, it seems to me it does this in a way that only works well in very simple dependency injection scenarios.  As soon as there is a moderate level of complexity the developer is having to learn several different configuration techniques, some of which aren’t easy to use, and how to apply them.

Part 7 will look at Spring JavaConfig.

Advertisements

4 Comments »

  1. Rich,
    I would love to read an article (series of articles) about your opinion of AOP.
    Your current analysis of DI/IOC is great–thank you.
    Cheers,
    Avi

    Comment by Avi Farah — May 26, 2010 @ 5:00 am

  2. …Visitor recommendations…

    […]I am no longer certain the place you’re getting your information, but great topic.[…]…

    Trackback by implanturi dentare pret — May 6, 2012 @ 7:21 am

  3. It looks to me that licencsing, goals like -> performance of framework in Serverside apps in multi-threading scenarios etc., should also be considered besides scenario driven thing that’s described above. Also, other frameworks like the one that’s in java 5 and above can also be considered. Good article. Regards, Sai

    Comment by Sai — October 1, 2013 @ 10:56 am

  4. Hi Rich,
    Can you send me your guice code of movielister, I can’t get here. My email is fqyyang@gmail.com. Thank you very much if you could help me.

    Comment by Paul — July 30, 2015 @ 8:08 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: