Constructor Annotations
Lombok provides three annotations that generate constructors so you never hand-write the assignment boilerplate. The most important for Spring developers is @RequiredArgsConstructor, which produces the perfect constructor for dependency injection into services and controllers.
The three constructor annotations
| Annotation | Generated constructor parameters |
|---|---|
@NoArgsConstructor | none (empty constructor) |
@AllArgsConstructor | every field, in declaration order |
@RequiredArgsConstructor | only final fields and @NonNull fields |
import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class Customer {
private final Long id; // "required" — final
@NonNull private String name; // "required" — @NonNull
private String email; // optional
}
This generates three distinct constructors:
public Customer() {} // @NoArgsConstructor
public Customer(Long id, String name) { // @RequiredArgsConstructor
this.id = id;
this.name = name;
}
public Customer(Long id, String name, String email) { // @AllArgsConstructor
this.id = id;
this.name = name;
this.email = email;
}
@NonNull fields also get a null check in the generated constructor, throwing NullPointerException early if a caller passes null.
@NoArgsConstructor for frameworks
Many frameworks instantiate objects reflectively and require a no-arg constructor — Jackson deserialization and JPA entities are the classic cases.
@Entity
@Getter
@Setter
@NoArgsConstructor // required by JPA
@AllArgsConstructor
public class Book {
@Id @GeneratedValue
private Long id;
private String title;
}
If a final field has no initializer, a plain @NoArgsConstructor will not compile. Use @NoArgsConstructor(force = true) to initialize finals to their default values (0, null, false):
@NoArgsConstructor(force = true)
public class Snapshot {
private final Instant takenAt; // forced to null
}
@RequiredArgsConstructor for Spring injection
This is the idiomatic way to do constructor injection in Spring Boot. Declare your dependencies as private final fields and let Lombok generate the constructor — Spring autowires it because the class has exactly one constructor.
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentClient paymentClient;
private final NotificationService notificationService;
public Order place(OrderRequest request) {
Order order = orderRepository.save(request.toEntity());
paymentClient.charge(order);
notificationService.confirm(order);
return order;
}
}
Lombok generates the constructor below, and Spring injects all three beans through it — no @Autowired needed:
public OrderService(OrderRepository orderRepository,
PaymentClient paymentClient,
NotificationService notificationService) {
this.orderRepository = orderRepository;
this.paymentClient = paymentClient;
this.notificationService = notificationService;
}
This pattern keeps dependencies final and explicit, makes the class trivial to unit test (just call the constructor with mocks), and avoids the pitfalls of field injection. See Autowiring for how Spring resolves these constructor parameters.
Tip: When a bean has two beans of the same type, you still need
@Qualifier. Place it on the field and Lombok copies it onto the generated constructor parameter (enable this with thelombok.copyableAnnotationsconfig or it works for@Qualifierout of the box in recent versions).
Combining with @Data
@Data already includes @RequiredArgsConstructor. To add the others, stack the annotations explicitly:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductDto {
private Long id;
private String name;
private BigDecimal price;
}
Warning: When you add an explicit constructor (generated or hand-written), Java no longer supplies the implicit no-arg constructor. If a framework needs one, declare
@NoArgsConstructorexplicitly rather than relying on the default.