More tests on Guice

In my previous post, I compared Guice and Spring JavaConfig. The conclusion is that, for my application, Spring is much easier to use and less verbose. However, the major force of Guice I didn’t talk about is it’s ability to inject Singletons into large applications in a very (very) effective way.

Let’s say you want to inject the same instance of an interface into hundreds of objects :

  • With Spring, you’d declare a bean for each of these hundred objects, so that you can inject the singleton.
  • With Guice, you just annotate the singleton interface with @ImplementedBy(SingletonImpl.class) and annotate each object with @Inject where you need to inject the singleton implementation. Result : not a single line of configuration and it’s faster at runtime than Spring.

Next time, I’ll check if Spring’s @Autowired annotation can do similar things.

4 thoughts on “More tests on Guice”

  1. I could be biased (as I’m working for SpringSource) but here’s my (not SpringSources) two cents:

    Guice does well on many points, but @ImplementedBy is not one of them.

    If you have one interface and only one implementation you have a classic example of over engineering triggered by a bad interpretation of a good design principle.

    The principle “Program to an interface, not an implementation” is not based on the Java language and hence ‘interface’ doesn’t mean ‘public interface …’. It just means that you should program to the contract defined by a certain supertype (to which all subtypes should comply by the Liskov principle).

    Iaw, if you have one single class that is both the interface and the implementation there is nothing wrong with that. Extract interface is a cheap refactoring in any serious IDE. Death to the Impl suffix!

    When you do need the interface it means that you have had to refactor your application to support *multiple* implementations. Tying the interface to one implementation is completely backwards in that scenario and a direct violation of the principle above.

    Spring does a little better with @Autowired and component scanning, but this is also pretty fragile with multiple implementations. You define which implementations to use externally (inversion of control remember?) either in xml, Javaconfig or a Guice module, whichever makes you feel comfortable.

    Cool to see you do an objective comparison of Guice and Spring. I’ll be watching your next posts.

  2. Thanks Iwein, I’ll try @Autowired and component scanning. I don’t totally agree with your analysis. I often have only one implementation for each interface but still create a Java interface to facilitate mocking. In production, for the majority of my interfaces, I’ll have only one implementation, so @ImplementedBy is quite handy. However you’re right that external configuration is better, and I’d better use explicit binding with Guice instead of @ImplementedBy. Still, Guice will make it very easy compared to Spring. We’ll see how component scanning can solve the problem.

  3. We certainly never intended @ImplementedBy to be the dominant way of binding interfaces to implementations (and it isn’t). It solves a few use cases nicely; barely enough to warrant its inclusion.

  4. I didn’t manage to configure component scanning from JavaConfig (don’t want an hybrid configuration)…

Comments are closed.