# Constructor Injection — Spring Boot

Source: https://www.skillbyai.com/en/spring-boot/d-ctor

> 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.

```java
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.

**Quiz:** Why is constructor injection preferred?

- [ ] It is the only way Spring works
- [x] 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.
