Backend Development 7 min read

Why You Should Stop Using Field Injection in Spring Boot

The article explains the drawbacks of field injection in Spring Boot—such as poor testability, loss of immutability, tighter framework coupling, risk of NullPointerExceptions, and hidden circular dependencies—and demonstrates how constructor injection provides a cleaner, more maintainable alternative with clear code examples.

Architecture Digest
Architecture Digest
Architecture Digest
Why You Should Stop Using Field Injection in Spring Boot

In Spring Boot, developers often debate the best way to inject dependencies: field injection, setter injection, or constructor injection. This article focuses on the disadvantages of field injection and presents a case for avoiding it.

What is Field Injection?

Field injection uses the @Autowired annotation directly on a private field, as shown below:

@Component
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;

    public Order findOrderById(Long id) {
        return orderRepository.findById(id);
    }
}

Why Stop Using Field Injection

1. Testability

Field injection makes unit testing difficult because the dependency is hidden inside the field, requiring reflection to replace it with a mock.

@RunWith(SpringJUnit4ClassRunner.class)
public class OrderServiceTest {
    private OrderService orderService;

    @Mock
    private OrderRepository orderRepository;

    @Before
    public void setUp() throws Exception {
        orderService = new OrderService();
        // This will set the mock orderRepository into orderService's private field
        ReflectionTestUtils.setField(orderService, "orderRepository", orderRepository);
    }
    ...
}

Using reflection violates object‑oriented principles and makes tests harder to read and maintain.

2. Immutability

Field injection leaves beans mutable after construction, whereas constructor injection creates immutable objects.

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

With constructor injection the dependency can be declared final and cannot be reassigned:

@Component
public class UserService {
    private final UserRepository userRepository;

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

3. Tighter Coupling to Spring

Field injection ties the class to Spring’s @Autowired , making it harder to reuse the class in non‑Spring contexts or to switch to another DI framework.

Non‑Spring applications would need refactoring to remove the annotation.

Switching to Guice or another framework would require extensive changes.

Developers unfamiliar with Spring may find the annotation confusing.

4. NullPointerException Risk

If a bean is instantiated outside the Spring context, its @Autowired fields remain uninitialized, leading to NPEs.

@Component
public class PaymentGateway {
    @Autowired
    private PaymentQueue paymentQueue;

    public void initiate(PaymentRequest request) {
        paymentQueue.add(request);
    }
}

public class PaymentService {
    public void process(PaymentRequest request) {
        PaymentGateway gateway = new PaymentGateway();
        gateway.initiate(request); // NPE here
    }
}

5. Hidden Circular Dependencies

Field injection can mask circular dependencies, making them harder to detect.

@Service
public class AService {
    @Autowired
    private BService bService;
}

@Service
public class BService {
    @Autowired
    private AService aService;
}

Constructor injection causes Spring to fail fast with a BeanCurrentlyInCreationException , revealing the problem early.

Conclusion

Although field injection looks concise, its disadvantages outweigh the benefits. Constructor injection improves testability, enforces immutability, reduces coupling, avoids NPEs, and makes circular dependencies obvious, aligning with SOLID principles and resulting in more maintainable Spring Boot applications.

Therefore, it is recommended to stop using field injection in Spring Boot.

JavaSpring Bootdependency injectionConstructor InjectionField Injection
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.