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.