https://sundaland.tistory.com/27
[ ▶ @RequiredArgsConstructor ]
[ ▷ 기본 개념: @RequiredArgsConstructor ]
@RequiredArgsConstructor는 Lombok이 제공하는 어노테이션으로, 클래스에 있는 final 필드와 @NonNull로 표시된 필드를 위한 생성자를 자동으로 생성해 준다. 해당 필드들은 반드시 초기화되어야 하기 때문에, 생성자를 통해 의존성을 주입받거나 외부에서 값을 설정받는 경우에 유용하다.
△ 자동 생성되는 생성자
이 어노테이션이 적용된 클래스에는 다음과 같은 생성자가 자동으로 생성된다.
- 클래스에 있는 모든 final 필드
- @NonNull로 표시된 필드
이러한 필드들이 생성자의 파라미터로 추가되며, 생성자 내에서 필드 초기화가 자동으로 이루어진니다.
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
private String notificationMessage;
// @RequiredArgsConstructor에 의해 다음과 같은 생성자가 자동 생성됩니다:
// public UserService(UserRepository userRepository, EmailService emailService) {
// this.userRepository = userRepository;
// this.emailService = emailService;
// }
}
위 예시에서, UserService 클래스에는 final로 선언된 userRepository와 emailService가 있다. @RequiredArgsConstructor는 이 두 필드를 파라미터로 받는 생성자를 자동으로 만들어 준다. notificationMessage는 final이 아니므로 생성자에서 제외된다.
[ ▷ @NonNull 필드 처리 ]
@NonNull로 표시된 필드는 반드시 null이 아닌 값이 설정되어야 한다. 이를 보장하기 위해, 해당 필드가 생성자의 파라미터로 포함되며, 생성자 내에서 null 체크가 자동으로 추가된다. 만약 null이 전달되면 NullPointerException이 발생하게 된다.
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class AccountService {
private final AccountRepository accountRepository;
@NonNull private EmailService emailService;
// 자동 생성된 생성자:
// public AccountService(AccountRepository accountRepository, EmailService emailService) {
// if (emailService == null) {
// throw new NullPointerException("emailService is marked non-null but is null");
// }
// this.accountRepository = accountRepository;
// this.emailService = emailService;
// }
}
[ ▷ staticName 속성: 정적 팩토리 메서드 생성 ]
staticName 속성은 클래스에 정적 팩토리 메서드를 생성하기 위한 옵션이다. 기본적으로 생성자는 new 키워드를 통해 호출되지만, 팩토리 메서드를 사용하면 객체 생성 방식을 보다 직관적이고 명확하게 표현할 수 있다.
@RequiredArgsConstructor(staticName = "of")와 같이 staticName 속성을 지정하면, 생성자 대신 정적 메서드를 호출하여 객체를 생성할 수 있다. 이 때, 메서드 이름은 of와 같이 지정한 이름으로 생성된다.
▼ 정적 팩토리 메서드
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(staticName = "of")
public class User {
private final String name;
private final int age;
}
위 코드에서는 User 클래스에 대한 of 메서드가 생성되며, 이를 통해 객체를 생성할 수 있습니다.
public class Main {
public static void main(String[] args) {
// 정적 팩토리 메서드 of()를 통해 User 객체 생성
User user = User.of("John", 25);
System.out.println(user);
}
}
이 예시에서 User.of("John", 25)을 호출하면, User 객체가 생성된다. 이렇게 정적 팩토리 메서드를 사용하면 객체 생성을 보다 직관적이고 의미 있는 이름으로 처리할 수 있다.
[ ▷ @AllArgsConstructor와의 차이점 ]
Lombok의 다른 생성자 관련 어노테이션으로 @AllArgsConstructor가 있다. 이 어노테이션은 모든 필드를 파라미터로 받는 생성자를 자동으로 생성해 주지만, @RequiredArgsConstructor는 final 필드와 @NonNull 필드만을 생성자 파라미터로 포함한다.
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
@AllArgsConstructor
public class CompleteUser {
private final String name;
private int age;
}
// @AllArgsConstructor 생성자:
// public CompleteUser(String name, int age) {
// this.name = name;
// this.age = age;
// }
@RequiredArgsConstructor
public class PartialUser {
private final String name;
private int age;
}
// @RequiredArgsConstructor 생성자:
// public PartialUser(String name) {
// this.name = name;
// }
[ ▷ 장점 및 사용 이유 ]
- 보일러플레이트 코드 제거: 필드 초기화를 위한 생성자를 수동으로 작성할 필요가 없어 코드가 깔끔해진다.
- 객체의 불변성: final 필드를 사용하는 생성자는 클래스가 불변(immutable) 객체로 설계되도록 돕는다.
- 명확한 의존성 주입: 클래스 생성 시 필요한 의존성을 명확히 드러내기 때문에, 의존성 주입 패턴에서도 매우 유용하다.
- 정적 팩토리 메서드 활용: staticName 속성을 통해 생성자보다 명확한 메서드 이름을 사용하여 객체 생성 방식을 좀 더 유연하고 직관적으로 할 수 있다.
[ ▷ 종합 정리 ]
- @RequiredArgsConstructor는 final 또는 @NonNull 필드를 초기화하는 생성자를 자동으로 생성해 주는 Lombok 어노테이션이다.
- staticName 속성을 사용하면 정적 팩토리 메서드를 생성하여, 직접 생성자 호출 없이 메서드를 통해 객체를 생성할 수 있다.
- 팩토리 메서드는 코드의 가독성과 객체 생성 방식을 명확히 해주는 장점이 있다.
- @AllArgsConstructor와 달리, 필요한 필드만 포함된 생성자를 만들 수 있어 객체의 의존성 관리를 더 명확하게 할 수 있다.
'Spring Boot > Annotations' 카테고리의 다른 글
Lombok (1) | 2024.10.16 |
---|---|
@SessionAttributes / @ModelAttribute 란? (2) | 2024.10.16 |