Spring Pitfalls

I enjoy working with Spring. It’s been very obvious from the first time I’ve with Spring that it’s extremely well thought out and solves problems in a very academy/computersciency way. Building your code around dependency injection makes it inherently more testable and forces you to really think about your interfaces and abstract classes. I have many things I love about the Spring ecosystem but in this post I want to discuss some of the pitfalls of overusing the flexibility that comes with the framework and offer some of my personal best practices. Please disagree with me on twitter @bweidlich! I would love to hear your take.

Monolithic Spring Contexts

Don’t do it. Think about the lifecycle of your context. Do you want to be able to refresh it, destroy it, alter it? It’s bad practice to bundle dynamic and static components in the same context.
Static components are your sessions, transaction management etc. Things you wouldn’t imagine refreshing or reloading. If you’re using xml files to wire up Spring dependencies then you could change behavior at runtime by swapping out xml files and refreshing your context. For example, if you’re using a job scheduler and you define your jobs in a Spring xml file you could refresh those job definitions while the application is running.
Think of your static context as your parent context and your dynamic context as your child. The parent doesn’t know about the child but the child can use beans defined in the parent. (Yay AngularJS folks, this sounds familiar! Scope inheritance & isolated scopes FTW!)

AbstractApplicationContext parent = new ClassPathXmlApplicationContext(new String[]{"classpath:META-INF/spring/staticContext.xml"});

AbstractApplicationContext child = new ClassPathXmlApplicationContext(new String[]{"classpath:META-INF/spring/dynamicContext.xml"},parent);

Another way to think of a single context is like a Docker file. You’re describing refreshable state and you wouldn’t put all your micro services into the same Docker file.

Setter-based injection

I’ve been removing setter-based dependency injection wherever I see it. The constructor should be the place where required dependencies are added. If the class should not function without it then add it in the constructor. This is also where you should add validations.
Whenever I see a service getting wired up using setter injection I cringe. Service dependencies such as data access objects (DAOs) that are not expected to change during the lifetime of the object shouldn’t be accessible. I’m a fan of starting with immutability and then relaxing those rules if needed.

Injecting into static classes

This is where Spring gets a bit scary and will appear as magic. Spring technically allows you to create a service with only static methods. You can wire everything into the static class at startup and then it just kinda exists. Confusing as hell. Your class now also requires a dependency injection framework in order to function properly. Don’t ever make your classes depend on Spring or any other dependency injection framework.

(to be continued in future posts)

Tell me your common Spring pitfalls and tips & tricks @bweidlich


Now read this

Wrap a REST API with Retrofit

Building a type-safe wrapper around a REST API is a pain. You need to deal with separate HTTP calls, dynamic construction of query strings, casting to your data types, handling exceptions etc. Luckily the smart folks at Square released a... Continue →