For quite some time it was obligatory to use Spring in a Java project; it became a defacto standard. Once you’re familiar with dependency injection you don’t want to code without it. One alternative to Spring was and still is PicoContainer. But then Guice came along: Googles lightweight dependency injection framework. I investigated it at the time it was released and now I wrote a simple comparison between Guice, PicoContainer and Spring because I’d like to integrate one framework into a project I’m working on.
If you’d like to read and watch something about Guice or Google check out the following links:
- the authors of Guice, Bob Lee and Kevin Bourrillion, present Guice
- Bob Lee presents Guice at the Google Developer Day in Beijing
- Kevin Bourrillion explains to his wife what extraordinarily typesafe means
- watch this short video or check out Googles channel on YouTube to get an impression how they’re working and what they’re working on – quite interesting.
During this comparison I’ll try to focus on DI only. To conclude that, say, Guice or PicoContainer is better than Spring, would be too general to be useful, since Spring is a lot more than just a DI framework.
I hacked together a simple test that was meant to identify the pros and cons of Guice, PicoContainer and Spring. You can download the Eclipse project as tar.gz or zip or browse the code here; although not needed, you may want to install the Spring plugin for Eclipse. I recommend installing the AspectJ Development Tools, but if you don’t want to install them, make sure to delete the
ajnature from the
.project and the
ASPECTJRT entry from the
If you start looking at the code check out the
ComparisonTest class first, as everything is bootstrapped from there.
All the test does is creating a hierarchy of objects:
- the class
SuperManageris the top-level class of the hierarchy
- the three classes
ComputationManagerare dependencies of
- the utility class
OutputHelperneeds an implementation of
Output, i.e. either
- one instance of
OutputHelperthat uses an instance of
SystemOutOutputis handed to
OutputManager1and another instance of
OutputHelperthat uses an instance of
LoggerOutputis handed to
ComputationManagerreceives an instance of
ComputationHelperand is handed to the instance of
Have a look at the dependency graph:
Following I’ll list things that I noticed using Guice, PicoContainer and Spring.
The first thing you’ll notice is that Guice makes extensive use of Java 5 language features, i.e. generics and annotations. While generics lead to the extraordinary type safety mentioned by Kevin Bourrillion, annotations couple your code to the Guice framework. If you’re really picky about loose coupling you might ask why you should use a framework that adds a dependency to itself?! You end up with lots of imports of the
Inject annotation scattered all over your code base. And it’s getting worse if you have to use
ImplementedBy and so on and so forth. You may want to define that elsewhere because your classes shouldn’t know anything about their usage (e.g.
Singleton) or where dependencies should be injected (
Inject) – that’s what inversion of control is all about, isn’t it?
However, for those who aren’t so picky there are some really cool things about Guice:
- it is type safe
- it reports sane error messages
- it is small and very fast
Well it is really type safe: if you ask Guice to give you an object of type
Bar it’ll do so – no cast to
Bar required. The authors of Guice don’t want it to be used as a simple service locator for a good reason: your code would still be coupled very tightly. That being said you want to call Guice only in some places in your code where it hands you a top-level class (e.g. a class like
SuperManager) where all the dependencies are injected. Whether you’ll have to do a cast on these few occasions shouldn’t be that bad; this puts the big feature of type safety into another perspective (read: isn’t that important). But this is definitely a plus for Guice though.
Reasonable error messages are one point for Guice: if something goes wrong you can identify the problem easily. From a user’s perspective this should be the case anyway but Guice manages this very well – as far as I noticed it.
Finally I’d like to credit Guice for being fast. I haven’t written performance tests myself but Bob Lee wrote a test in March 2007. He came to the conclusion that Guice is more than 50 times faster than Spring. I ran the test lately and got the following results (average of ten test runs):
So it boils down to this:
After that, Guice (1.0) seems to be only 10 times faster than Spring (2.0.6). Have a look at another performance test here.
PicoContainer is a nice piece of software that facilitates dependency injection without much overhead: no external configuration files (read XML files) and no annotations needed. All you have to do is register your components with the container; for small projects this is an effortless thing.
As with Guice you write everything in Java and can reap the benefits of your IDE’s refactoring capabilities: if you change a class’s name all references will be changed too.
PicoContainer supports the concept of a lifecycle; it isn’t that relevant for my comparison, so if you’re interested you can read about it here.
Spring is the ultimate dependency injection framework serving the industry for several years. Some years ago every tool had to have an XML configuration; Spring came along with a fancy one and bingo – (almost) everyone liked it. First of all, Spring doesn’t have the aforementioned cool features of Guice or PicoContainer: it is not type safe and doesn’t leverage existing refactoring tools of your IDE (that is Eclipse in my case) – update: the latter isn’t true.
Despite these flaws Spring is well established and seems like a good investment into the future. Opposing to Guice, Spring doesn’t introduce a dependency to itself by default. As long as you don’t use any special features of Spring, your code base will be completely abundant from any dependency injection framework, i.e. if you’d like to go back to dependency injection by hand, you can do so without deleting any annotations or special import statements. You just have to get rid of the XML configuration files.
Spring seems to be harder to use than Guice: without autowiring you have to specify the dependencies between your beans in a very verbose manner, i.e. you have to think about the things you’d like to do and write them down in a configuration file. Ideally you don’t have to specify anything with Guice, except the
Inject annotations and Guice will handle everything for you.
Another difference I noticed is that Spring uses singletons by default while Guice doesn’t. If you want a class to be a singleton you’ll have to use the
Singleton annotation with Guice. Obviously, both approaches have their strength and weaknesses.
It’s a tough decision to choose one of these frameworks – obviously they’re all pretty cool. First I opted for Guice because I like experimenting with new, bleeding-egde software. But as I mentioned earlier, there might be people on your team who think that all these annotations couple the code to Guice – this takes some evangelizing. Spring, on the other hand, is known for its verbose configuration but also for its robustness and being future-proof.
To draw a conclusion I think choosing between Guice, PicoContainer and Spring, for lack of a hard and fast rule, will be to do what works best for your project. Currently I would recommend using Guice for dependency injection: if you use the annotations wisely they’ll unobtrusively document your code and since you’ll do everything “the Java way”TM refactoring will be really fun.
19 thoughts on “Comparison between Guice, PicoContainer and Spring”
Hi Christian! I loved this post. You certainly hit the nail on the head when you said that all these frameworks are cool — the only way to really mess up is to try to build anything real without one of them.
I’m off to blog a more detailed response.
I couldn’t agree more with your assessment. Spring introduces cumbersome XML files but is more transparent. Guice on the other hand is less cumbersome to use but is less transparent. Like you said, there is no need to remove annotations (rather easy task) when moving to new framework. I have implemented two plug-in frameworks using Spring and annotations (Microsoft CAB) and I prefer annotations.
That’s right: you could just leave the annotations in the code and probably nobody would care. You would have a compile-time dependency to Guice but that wouldn’t be too bad either.
Update: today I found out that e.g. renaming a class will rename it in Spring’s XML files, too. I’ve tested this with Eclipse 3.3 and Spring IDE 2.0.
Besides any comment on what you wrote, I would like to ask you to look at Tapestry5 IoC:
Maybe it’s better to look at
for the latest nightly docs from trunk.
It is still marked as alpha, but there are a lot of site/applications using it with success.
There’s another lightweight, open source, dependency injection framework that bundles ORM independence avoiding locking your code into one particular transparent persistence engine. You can use Hibernate, JDO (JPOX, Kodo etc) plus if you use another writing a new plugin for it is only a 30 minute job.
All the config is in minimalist Java (not XML) so you’ll find out at compile time if things aren’t right 😉
Very interesting post mate!
Thaks a lot for you effort on this one.
Pingback: ???????????? ????????? ??? Inversion Of Control « Java Hellenic User Group
I’m a little disappointed at the treatment of PicoContainer in this comparison. I have not used Guice (my research in considering it led me here) so I can’t comment on it, but I recently had a *terrible* Spring experience which is leading me far, far away from XML and the maintenance it brings.
I used PicoContainer years ago when first exploring DI and for that it seems to me the purest and by far lightest of the bunch plus no code dependencies at all except for dealing with the container at the top level, which all of them have.
I was reading here to see why Guice was better than PicoContainer since after their tutorial it looked identical except that I would have to use annotations all over my code. Why was PicoContainer dismissed with so little detail?
Two years ago when I wrote this post I had no experience with real projects which where using PicoContainer; this hasn’t changed since. I had a look at the available solutions and thought that PicoContainer was worth mentioning but nobody – in my experience – seemed to use it and so I didn’t write about it in more detail.
Fair enough, I have only used it for personal projects myself so I can’t find any fault there 🙂 However I am considering it as a serious option to replace Spring in a current “real” project (since we don’t actually make use of the extras that Spring brings and really only use the DI part of it); if I/we do I’ll post here with whatever experience I have.
Nice comparison, but Guice is not bleeding-edge. It is two steps backward to attempt to avoid the XML hell Spring creates. It is a massive trade-off.
If Guice (or Pico) are “two steps backward” from Spring to avoid XML hell, then obviously Spring was moving in the wrong direction. (Of course I could have told you that when I first was learning Spring – suddenly Java is not good enough and we are “XML Programmers” – hah!)
I’m a little annoyed at how Pico is overlooked here too, yes perhaps the experience wasn’t there to judge, but then that should probably be stated a little more up front to be fair. Pico seems like a more flexible choice than Guice: you CAN use annotations if you want, but you don’t have to at all. That’s pretty nice I’d say. Lack of dependencies (and Spring BLOAT) is a no-brainer and is HUGE, not something to be casually pointed out as a minor plus. Guice is definitely an excellent choice but I think Pico (which I believe came first) has the edge, technically speaking.
I see no “massive trade off” in not using Spring. Spring has reached it’s peak in popularity and now lives off hype and brain-dead management who bought into it. Pico and Guice don’t *need* huge communities because they’re so much simpler to use. The only trade off in not using Spring is that you’ll lose your buzzword compliance rating and the fuzzy feeling people get when they hear it on job interviews.
first off, again, I’m sorry that I didn’t cover PicoContainer in more detail – maybe this article is just a comparison of Spring and Guice.
Second, I don’t know what Bryon really meant but I don’t agree with this short statement either. All DI frameworks have the one or the other advantage and of course some disadvantages when compared to each other. Choosing one of them really depends on the specific context since none of them is the ultimate solution.
I like your cynical conclusion regarding Spring because I’ve observed this behavior as well. Anyway, I use both – Spring and Guice – on a regular basis and if I can’t influence the decision which DI framework should be used for a project, I just use it and don’t bother telling the client that he’s made the wrong decision because most of the time the disadvantages aren’t that bad.
“but nobody – in my experience – seemed to use it and so I didn’t write about it in more detail”
A little googling shows that Atlassian JIRA and the IntelliJ IDE (JetBrains) use PicoContainer at their core.
Some open source products also use it like Sonar. I’m pretty sure that plenty other companies use it without necessarily feeling the necessity to brag about it. Mostly, PicoContainer has to be mentioned to developers when the products have a extensible/plugin architecture.
thanks for proving me wrong – I’m always happy to learn how things really are 😉 Anyway, as I said earlier I must admit that this article just mentions PicoContainer but doesn’t cover it in much detail, my fault. If I ever find the time to write such a decent blog post again I’ll try to avoid issues like this one.
First of all nice article Christian,I liked it.
Actually we were using the picocontainer as a DI in our project, so initially i was bit fiss regarding the usage of this open source rather than spring which was proven right.
but more i think about it it depends on where you really deploying the code, we do nt have an application server, we are hosting in our home grown servers and have the standalone appls,So i thought it would be pretty easy to hvae the simplest DI(Pico) rather than having the dependencies with the application servers to read up the configuration XML files.
More over ppl who liked to work on maps and doesnt like XML stuff can also chose pico.
and very important point is if you are only looking for DI rather than other feature where spring sup[ports you may go for PICO.
Hello Vamshi Krishan Dachavaram,
sure, you may be right and Pico may be the right choice in some circumstances. Sometimes it just depends on the frameworks a certain team is used to and it doesn’t make much sense deciding which technology is used on each and every project. The point I’m trying to make is that it’s nice having a certain basic infrastructure to build applications and if these happen to be web applications you might always opt for Spring – or something else of course – so it gets easier switching between projects because all of them use the same foundation. Just a side note I just thought of.
Comments are closed.