Why Guice is better than Spring

10 reasons why Guice is better than Spring

Posted: Thu 27 Feb, 2014, 19:00
  1. Guice is just Dependency Injection.

It all started with DI and/or inversion of control (IOC). This all Guice is, and all it has ever been. It's also the stated goal of the project owners, it's not the kitchen sink. So if this is what you need, then you should use Guice. It mandates nothing, it doesn't get involved where it's not needed and it leaves you free to choose the right APIs for the rest of your application without fear or favour. 2. #### Using Spring does not make you a good developer With Spring you very quickly end up in a Spring-way of doing things in a much more laborious, cumbersome and less type-safe way, when all you needed was just good DI. Many people think that if teams are using Spring then they are following best practices and writing good code. Many of managers also assume this, unfortunately. In my experience, this has not always been the case. I have seen truly awful code within applications that use Spring. I've even seen a team removing Spring, and going back to no DI, because it was deemed to have made things worse for the team. Spring can be used effectively as a they need dependency injection, what they are trying to avoid/achieve and therefore select the best tool for this purpose. Many developers still manage to tangle code together even though they are supposedly using Spring and make unit tests a nightmare to write. If you use Guice, then the chances are you get what are doing and you will end up with better code. 3. #### Guice has led the way where others follow Defining how objects are dependant on each other is a tricky thing to express, it's codifying your object graph after all. Hence Spring broke out the XML and shoved it outside the application. Guice leveraged Annotations, that were defined within Java code from the start, to inject directly. If you do a typo or anything, the compiler will highlight this staight away in the IDE. I understand that Spring now supports other ways of defining Java dependencies, but I've only ever seen XML used in practice. Also, the @Inject annotation is now part of the Java API - it originated with Guice. 4. #### No need to use XML. If it is in XML is must be good. Eh.... why? Why would I want to hack about writing chevrons and backslashes in a file that is detached from my Java code if I didn't have to. Seriously though, this was and with many still is the prevailing opinion. People forget that they are dealing the code, objects, classes and so the best way to work with such constructs is in... eh code. Eclipse (or your IDE of choice) will take care of all your refactoring for you so that you don't have the secondary task of updating the references in XML. 5. #### jersey-guice is awesome OK, so they do offer a couple of modules that allow you to leverage their flavour of DI with very, very commonly used application APIs. For example, you can integrate with JPA or Servlets. A huge proportion of applications in Java are going to need one or both of these - so it's kind of an essential requirement. The Jersey-Guice module is an extension to this so that you can easily create build Jersey REST applications that leverages Guice behind the scenes. Jersey in itself is great and when used with Guice, it's an awesome combination. 6. #### @AssistedInject is good and necessary Sometimes you have an object that you need to create and it needs an object that is not available to your DI framework. It's something that you have at that point in your code, that you got from somewhere else. You could do a , but you are then back into bad practices and tangled code. @AssistedInject is what you need to facilitate dynamic creation of objects whilst still maintaing good DI. There is no equivalent in Spring. You cannot do a getBean(foo, bar) where you provide the foo and have Spring inject it into the the bar object for you.For example, say during runtime you end up with a URL and you need to use this URL to construct a new object. The new object has it's own other dependencies as well. In Spring, it would be possible to construct the object with all the Spring-owned dependencies, but then an extra call would be necessary to set the URL at the end. This is not as clean and safe because the URL variable cannot be final, so there will need to be checking to make sure the URL is not null. With Guice, you can still use constructor injection with @AssistedInject which allows some dependencies to be provided at run-time and some to provided by Guice. Very nice. 7. #### It encourages good practices - for example using final and no casting Everyone should be using constructor injection and finals, and Guice actively encourages you to do this. Constructor injection is far superior to method injection because then you can use final and not worry about what is/is not null in your class. If, for whatever unfortunate reason, you do need to use the Injector (Guice) or ApplicationContext (Spring) directly to get objects from the CI container, then Guice has better support. With Spring you need to know what type is going to be returned and cast it onto an object of that class - which is never a good model as it will only fail at run-time. With Guice you need to tell it what type you are expecting and even at build-time, it will let you know if the assignment will fail. Thanks for the power of templating, it's much nicer. 8. #### No false benefits Spring has the much vaunted benefit that it will protect you from specific implementations. I remember going on a Spring course years ago delivered by Interface 21 when it was explained to us that you did not have to choose/depend on a particular XML binding framework or Remoting framework. Well I've never found that ease of code conversion was the critical factor in determing if an implementation change should be made. A switchover is never painless. Things like the capability of the replacement, compatibility with existing, testing, developer awareness and changing the public API are all far bigger blockers than the ease of code change. For example, there are simply things that WSDL can support that Spring Remoting cannot, and vice versa, and Spring will not protect you from this. To pretend one can switch seamlessly is a myth. Unfortunately people often buy into this false security, and it's another misguided another reason for Spring's dominance. Spring has been owned by VMWare since 2009 and is presumably a key component of their strategy going forward. They now offer some licensed Spring tools and add-ons that can help you get more out of Spring, like Insight, vFabric, tcServer (which is Tomcat) and their Web Server (which is Apache HTTP Server) products. Nowadays, Spring will lead you into a commerical walled-garden, so be careful out there! Choosing a DI framework should really have no bearing on all these wider architectural choices, so Guice will keep your options open. There is so much support, integration, abstraction and inter-dependencies that bringing in one new module will bring in a tonne more. Before you know you've had to include all the "optional" modules and your application is enormous. 9. #### Application Configuration != Dependency Injection Let me try and explain this one. I think application configuration is still the most poorly implemented aspect of industrial Java application development. I've never seen any application that implements it nicely. I've lost count of the number of weeks I've spent picking through properties files trying to figure out what it all does. I personally think the problem is compounded when Spring is used, which enables developers to build a template of the instances/wiring that will together define their runtime application. This means Spring is now the DI framework the configuration owner, with named instances hard-wired into other named instances of objects. As an operating model for an application, this means the your application. One example I can give is of an application that I owned for a while which utilised multiple internal queues, each processing different jobs on each queue. It was quite an old Java application (running Java 1.2 initially), and did not have any DI and no unit tests (yep, it was tough to develop and even harder to test). So rather than having a static DI/configuration file, the "shape" of the application on startup was dictated by configuration in a database. This was actually really nice. It was possible to configure more queues, more workers, different flows just by changing the database configuration. It would be very unusual to find such flexibility in a Spring application today, because the DI definition also the template for the application startup (all you can tweak are properties). Few people see the distinction between the two. Choosing Guice will leave you more flexibility to control the precise run-time application profile based on mutable configuration of your own design. 10. #### Guice is now at the top table with Spring By being the plucky up-start against the prevailing competitor, they have actually brought Spring to the table and allowed a concensus to be built around what DI should be in Java and how it should work. Thanks to JSR 330 the core facilities are now available in the Java API (6 onwards) so that in fact applications can use standard Java annotations now without having to choose Spring or Guice or anything else for that matter. The flagship annotation for this API is the @Inject annotation, which was something the Guice authors have been using since the start. In fact if you look at the specification, everything originated with Guice, I don't recognise anything from Spring even. Not even @Autowired. Spring has supported JSR 330 since the first draft. That Guice should have equal billing with the Spring behemoth on this important standard is testament to the respect it has gained in the Java community. It's often true, and logical, that the second generation alternative is better than established incumbent. Whilst Guice was first released in 2006/7, Spring's first milestone release came in 2004. By being second, you improve on what has gone before, refine it and learn the lessons. And so it was with Guice.

Here are some other points of view: