Lesson 5 / 25
Constructor Injection
Required dependencies, immutable fields.
Prefer constructors over field injection
Declare dependencies as constructor parameters: Spring passes the matching beans when it creates the object (a single constructor needs no @Autowired). Fields can be final, the class cannot exist without its dependencies, and tests can construct it with plain new. Field injection (@Autowired on fields) hides dependencies and makes testing harder. Too many constructor parameters is a sign the class does too much.
A service with constructor injection
This file is from a demo "shop" service generated by start.spring.io for Spring Boot 4.1.1 and Java 21 (Temurin 21.0.12), built with Maven 3.9.16; the project compiled and its tests passed. The repository is injected through the constructor; methods declare transaction boundaries.
package com.example.shop;
import java.math.BigDecimal;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ProductService {
private final ProductRepository repository;
public ProductService(ProductRepository repository) { // constructor injection
this.repository = repository;
}
@Transactional(readOnly = true)
public Product get(long id) {
return repository.findById(id).orElseThrow(() -> new ProductNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Product> cheaperThan(BigDecimal max) {
return repository.findByPriceLessThanOrderByPriceAsc(max);
}
@Transactional
public Product create(String name, BigDecimal price) {
return repository.save(new Product(name, price));
}
}Keep constructors small
More than four or five dependencies usually means the class should be split.
Quick check: Why is constructor injection preferred?
- It is the only way Spring works
- Dependencies are explicit, fields can be final, and tests can use new
- It makes startup slower on purpose
- It hides dependencies
Answer
Dependencies are explicit, fields can be final, and tests can use new — Explicit and testable.