How-to Migrate from Spring Framework to Guice
Iteration 0 – Stable Spring Application
We start from a Spring application that is stable, all automated tests are running and has been tested by ourselves. Assume we are using Spring Test Framework.
Let’s learn to walk before learning to run. Assume that we are the only developers on the project, and that it’s a little application.
If you don’t have any Java application for following this how-to tutorial, why don’t you implement an easy code kata? For example this one : Prime Factors (you can see UncleBob’s implementation following the link).
Someday I’ll give you the code of this how-to tutorial using a slyly modified version of this kata (warning, I’m a JEE-heavy-Spring style lover).
Iteration 1 – from Spring Test Framework to JUnit Framework
Our first step is changing our Testing Framework, unplugging the Spring Test Framework and replacing it for JUnit.
Remove Spring Test dependency from pom.xml (or remove the library from your class path). Test classes must extend junit.framework.TestCase. Test methods names must begin with “test” prefix (“primeNumberTest” is not a valid test method name, use “testPrimeNumber” instead).
Using JUnit for running test implies Spring no longer injects automatically required beans. We can choose to either use manually Spring API for create our Context and getting beans from it or use no ID at all. Let’s chose the second option to illustrate how an application works with 3 different injection’s mechanism (java old style, Guice style and Spring style).
All testing running? All green? Let´s continue.
Iteration 2: Dependency Injection: from Spring Framework to Guice Framework
Create Java classes for your Binding Modules (no need to say, into a new package for them). Remove your now useless XML Spring configuration files.
@Override
protected void configure() {
bind(RomanNumberBO.class).to(RomanNumberBOImpl.class);
bind(RomanNumbersValidation.class).to(RomanNumbersValidationImpl.class);
}
For each property, use Guice injector initialization them. You may now consider removing Setters of this properties, those which only purpose were being invocated by Spring in order to inject the dependency.
private RomanNumberBO romanNumberBO = Guice.createInjector(new RomanNumberModule()).getInstance(RomanNumberBO.class);
Test again. All right? All green? Then we’re done.
Migrating larger applications shared with more developers
Looks pretty easy, don’t you think? Migrating small applications where we are the only developers are easy. Big shared applications are not so easy to refactor, so don’t underestimated the task.
First step should be communicating the plan to all the members of your team, and close the details of the plan with them.
Second, all members who will participate in the migration process should complete a small migration process like the described above, or participate in “pair” programming session where one “expert” migrate one little module while the other are watching. If you prefer, a good document explain it could work too. My recommendation, both of them: first write the document, share it, be sure it’s read, and “pair” programming session.
The best strategy probably is starting from a 100% vs 0% modules used by old technology vs new technology, and as both technologies live together, begin migrate one by one modules from the littler and less critical until we reach the desired 0% vs 100%.
Continue with both technologies for a while (a few production deliveries) and when you feel comfortable, unplug all the remains of the old technology.



