2023. 4. 17. 15:25ㆍSpring Boot/Annotations
1. 기본 개념: @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
이 아니므로 생성자에서 제외됩니다.
2. @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;
// }
}
3. 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
객체가 생성됩니다. 이렇게 정적 팩토리 메서드를 사용하면 객체 생성을 보다 직관적이고 의미 있는 이름으로 처리할 수 있습니다.
4. @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;
// }
5. 장점 및 사용 이유
- 보일러플레이트 코드 제거: 필드 초기화를 위한 생성자를 수동으로 작성할 필요가 없어 코드가 깔끔해집니다.
- 객체의 불변성:
final
필드를 사용하는 생성자는 클래스가 불변(immutable) 객체로 설계되도록 돕습니다. - 명확한 의존성 주입: 클래스 생성 시 필요한 의존성을 명확히 드러내기 때문에, 의존성 주입 패턴에서도 매우 유용합니다.
- 정적 팩토리 메서드 활용:
staticName
속성을 통해 생성자보다 명확한 메서드 이름을 사용하여 객체 생성 방식을 좀 더 유연하고 직관적으로 할 수 있습니다.
종합 정리
@RequiredArgsConstructor
는final
또는@NonNull
필드를 초기화하는 생성자를 자동으로 생성해 주는 Lombok 어노테이션입니다.staticName
속성을 사용하면 정적 팩토리 메서드를 생성하여, 직접 생성자 호출 없이 메서드를 통해 객체를 생성할 수 있습니다.- 팩토리 메서드는 코드의 가독성과 객체 생성 방식을 명확히 해주는 장점이 있습니다.
@AllArgsConstructor
와 달리, 필요한 필드만 포함된 생성자를 만들 수 있어 객체의 의존성 관리를 더 명확하게 할 수 있습니다.
'Spring Boot > Annotations' 카테고리의 다른 글
@SessionAttributes / @ModelAttribute 란? (0) | 2023.08.08 |
---|---|
@Builder (0) | 2023.04.17 |