When @hoserdude & I stood up QuickBooks Self-Employed's backend almost 4 years ago, Spring Boot was the new shiny thing offering RoR type productivity in the Java world. We fell in love with Spring's Dependency Injection via the @Autowired
annotation - we used the annotation liberally, primarily on fields. I sold many developers on this technique until we started seeing more & more instances of class bloat and developers inadvertently creating instances in invalid states.
@odrotbohm's "Why field injection is evil" post explains the issues really well.
Anyway, I'm a convert now and avoid field injection. Even though our codebase is 4+ years old, I want to think we've been diligent about paying off tech debt and keeping dependencies, patterns, and designs up to date. Thanks to in no small part to @lerocha. However, we had a few nasty @Components that Autowired @Qualifier
fields in; moving these classes to constructor injection meant hand-writing constructors as Lombok's made-to-order-constructors feature didn't deal with Qualified beans. The thought of not being able to leverage the boilerplate-reducing abilities of Lombok meant developers stuck with field injection and in fact the pattern perpetuated.
I rejoiced when I saw Lombok's copyableAnnotation
feature in 1.18.4
. it was as simple as adding a lombok.config
in the project root with:
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
Boom! We are now able to move all these legacy classes to constructor injection. No excuses!
This post does a nice job of explaining via an example.