Face off: Guice vs Spring
Both Guice and Spring are Dependency injection frameworks which does the job of connecting the dots with right lines, so that we can kick start our service.
Essentially we use this to define which implementation to pick for an interface defined, so that it is picked up automatically during runtime. Since, dependencies are separated from an implementation, code becomes more unit testable.
First, lets look at the pros of using (Google’s) Guice over Spring.
Setter injections vs Constructor injection
Spring recommends us to avoid using ‘final’ on the dependencies and relies more on injection using setters. This takes away immutability from our classes as dependencies change be changed at runtime.
Guice recommends constructor injection over setter injection, though both are supported. Using finals are recommended in Guice and this makes our classes more robust.
XML Binding vs Type Checked Bindings
Spring uses XML to define the bindings between implementations. This brings in complexities when a wrongly typed object was bound to an interface, which can be found only during runtime. Even though this limitation was overcome by Java Configs on Spring, it is not a complete solutions. For many strategic bindings, java Config would use class names as strings for bindings, which would defeat the purpose of Static type checking.
This would also bring in complexities during development as well, since implementations are not navigable from code, when bindings are defined in XML. (Spring IDE does it. But why a new IDE just for this purpose? Limits IDE options to Devs)
Guice use java classes called Modules to define bindings. Unlike Spring, type checking is done at compile time and invalid bindings are detected in compile time. String based identifiers can also be used in Guice with @Named annotation, but usage of this is strongly discouraged (Bindings to Primitive type classes would use @Named). Any IDE would be able to navigate through the classes as things are statically typed.
Avoiding Null injections
Spring allows injection of Null as dependency when @Nonnull annotation is not used. This brings in complexity to do Null check on dependencies and prone to NPE during runtime. Spring also allows binding an interface to a Null.
Guice doesn’t allow null injections. When a binding is null, it fails fast so that we would catch it with a cleaner exception rather than receiving an NPE.
Heavy Weight vs Light weight
Spring is a heavy weighted framework which was built during earlier days of Java/J2EE. It has also tried to keep up with various new features introduced, such as Annotations, Generics, etc. Features such as Java Config and Annotations are added to spring to keep up with the advancements.
Guice was built ground up using all new features of Java so that it is light weight and statically typed.