Why Field Injection is Fading Away with Spring 5.0

“Unlocking the Secrets of Spring 5.0: How Constructor Injection is Building a More Secure and Testable Codebase.”

Eidan Khan
JavaJams
4 min readMar 26, 2024

--

Spring 5.0 brings a change that might seem small but is quite significant for developers: it suggests we stop using field injection. Let’s break down what this means in simple terms and why it’s important.

What’s Wrong with Field Injection?

Imagine you’re building a Lego house, and you have all your bricks mixed up in a big box. Every time you need a specific piece, you have to dig through the pile. This is a bit like field injection; it’s not very organized, and it can cause problems:

It’s Like a House with No Doors

With field injection, your code is like a house that you can’t enter because there are no doors. You can’t see what pieces (or dependencies) it needs without looking inside the code. It’s not clear, and it’s hard for others to understand what’s going on.

Testing Turns Tricky

Now, if you wanted to test if your Lego house is strong, but it’s all sealed up, how would you do it? It’s tough, right? That’s how it feels to test code with field injection. You can’t easily swap out parts to check if they work well.

Can’t Lock the Doors

In our Lego analogy, using final is like having a lock on your door. It keeps things secure and stops anyone from changing things inside. Field injection doesn’t let you use final, so it’s like having a house where you can’t lock the doors.

Too Tied Up

Lastly, field injection is like using a special glue that only works with one brand of Lego. It’s not great because you can’t use it with anything else. This is what happens when your code relies too much on Spring; it’s not flexible.

Why Constructor Injection Makes Sense

Constructor injection is like having a neat list of all the Lego pieces you need before you start building. It’s clear, organized, and makes it easy to swap pieces in and out:

  • Clear List: You know exactly what pieces you need right from the start.
  • Easy to Test: Testing your Lego house is easy because you can check each piece individually.
  • Secure: You can lock everything up tight with final, so no one can mess with your house.
  • Flexible: You’re not stuck with one type of glue, so you can build with any Lego bricks you want.

In Short

Field injection can make your code messy and hard to work with. Constructor injection keeps things tidy and safe. It’s like the difference between a cluttered, unlocked house and a neat, secure home. Spring 5.0 wants us to build better, safer code, and that’s why it recommends constructor injection.

Let’s explore how field injection compares with constructor injection through a simple service layer example.

Imagine you’re building a service in a Spring application that manages user accounts. This service will need access to a repository to perform operations like finding or saving user data.

Field Injection: The Messy Lego Box

With field injection, you might have a UserService class like this:

@Service
public class UserService {
@Autowired
private UserRepository userRepository;

public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}

At first glance, this seems convenient. However, this approach has several pitfalls:

  • The @Autowired annotation obscures the dependency, making it less transparent.
  • Testing this class requires reflection to inject a mock UserRepository, complicating the test setup.
  • The userRepository cannot be final, which means it can be reassigned, leading to potential issues in a multithreaded environment.

Constructor Injection: The Organized Lego Kit

Now, let’s refactor the UserService to use constructor injection:

@Service
public class UserService {
private final UserRepository userRepository;

@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

public User findUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
}

With this approach:

  • The dependency on UserRepository is explicit and clear.
  • The userRepository field can be made final, ensuring immutability.
  • Writing tests is straightforward, as we can pass a mock UserRepository directly into the constructor.

By using constructor injection, you’re ensuring that your ‘Lego house’ is built on a solid foundation, with all the right pieces in place, making it sturdy and reliable.

I hope you found this article helpful and enlightening. If you did, please show your support by clapping, leaving a comment, and sharing it with others. Additionally, you can also support my writing via, buy me a cup of coffee!. Your encouragement fuels my passion for writing and sharing knowledge. Let’s keep the conversation going and spread the word about best practices in Spring 5.0!

--

--

Eidan Khan
JavaJams

🚀 Full-stack Dev | Tech Content Creator 📝 For more in-depth articles, tutorials, and insights, visit my blog at JavaJams.org.