I like Guice, it’s a nice little tool that gets you all excited by doing Dependency Injection using annotations. That’s where it ends though, it really does. Once you’re past the high of using @Inject in a couple of your classes and on to doing something a little more complex, you realize that you’re a little stuck. And by stuck I don’t mean “totally f***ed” I just mean, you’re going to have to jump through some hoops to get it working, one of those hoops might even be refactoring for the sake of using Google Guice and throwing around annotations where you really don’t want annotations, like method parameters. The Guice guys will tell you your code probably sucked anyways and the refactoring is only helping your design – I wouldn’t buy it.
To me object lifecycle management is huge, you know, those methods for your classes which Spring so kindly allows using the InitalizingBean interface or init-method/destroy-method attributes, well that apparently is blasphemy to the Guice folk. Suffice to say they consider it bad practice and horrible design that one of your objects might need some initialization past the actual object creation. Some poor sap had a pretty damn good idea of having @Initialize type annotations for a method you might like to invoke after the object has been created, but he was quickly shot down by the Guice head-honcho who wasn’t convinced that there was a legitimate use-case for this. This effectively kills off anyone who might try to port their application over from Spring – their chief competitor. Instead of lifecycle methods, they want you to implement something called Provider interceptors, yeah, like that’s true DI!
The configuration is a mess, now whoever thinks they’d rather write Java code to configure their DI or IoC stuff instead of XML is beyond f***ed. That’s like saying why use Ant when you can just write one big Java class and do everything inside the main() method. I don’t care how hard they try to make Java code look like English, it still won’t cut it for me. If you prefer having classes in your application that have code like bind(Service.class). to(ServiceImpl.class). in(Scopes.SINGLETON) instead of an XML file, good for you, but I don’t see any benefit whatsoever in adopting this approach. I only see losses: the need for compilation, your configuration spread out in Java classes and difficulty in integrating your “Modules” with other tools.
Guice is also counting on you to create annotations of your own so that you can mark your own source code to help Guice figure out what it needs to do. Prime example is injecting constants, to inject a constant you would need to create a marker annotation, MyConstant and then do a bindConstant().annotatedWith(MyConstant.class).to(123456). Or you could use the @Named annotation which further clutters up your code base to the tune of introducing magic strings. I feel I have to do too much work to get Guice to behave the way I want it to behave, now I’m not lazy and am ready to put forth the effort but it shouldn’t come at the expense of writing custom Providers every time I need to play with a JAR’ed up class.
The good part about Guice is that you can use annotations for DI but the bad part is how messy the configuration classes can become, especially if you’re using third party JARs. The other thing that confuses me is that the Guice team seems to be very concerned about crossing some phantom preset boundaries that would make Guice do “too much” – the lifecycle methods are a prime example. If you’re seriously thinking about challenging Springb shouldn’t you provide a path for people who might actually test the migration? The best you can find is Eric Burke migrating a pea sized application over from Spring which doesn’t say much more than what the Guide says. I also lost faith in the Names class which I hoped would relieve some of the stress of wiring using Java but no such luck since Properties can’t resolve nested keys, but this class is a step in the right direction. They just need something like this, except something that can read in the interface to implementation mappings and other third party classes configuration.
I have a funny feeling that once Spring comes out with annotations for DI, the hype about Guice will die down significantly. Guice would be wise (I think) to actually have a bridge to allow for XML configuration as a supplement for wiring classes (I know it sounds crazy Bob). It would greatly eliminate the need to write Providers which I even feel yucky writing knowing that I’m actually writing code just for configuration sakes. Am I being weird in my thinking that we’re past the point of configuration in unadulterated Java code? I feel whatever is gained with annotations is immediately lost with the woeful configuration technique.