1. 개요
이번 포스팅에서는 생성자를 편하게 만들어주는 생성자에 대해 알아볼 것이다. 이전 포스팅에서 DI에 대해 알아보면서 장점이 많은 생성자 주입을 사용하는 게 좋다는 것을 알았다. 이 생성자를 내가 직접 만들 수도 있지만 Lombok에서는 어노테이션으로 지원을 해준다. @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor 이 세 개의 어노테이션이 각각 어떤 차이점을 가지고 어떤 상황에 사용해야 하는지 궁금해서 찾아봤고 정리해보려고 한다.
https://projectlombok.org/features/constructor
2-1. @NoArgsConstructor
@NoArgsConstructor는 말그대로 No:아무것도 없는 Args:인수(파라미터) Constructor:생성자 즉 파라미터가 없는 Default 생성자를 만들어준다.
@NoArgsConstructor
public class Member {
private String name;
private int age;
//아래와 같이 생성 됨.
public Member() {
}
}
@NoArgsConstructor 사용하는 경우
1. Entity Class / @Entity
- Entity를 생성하면 JPA에서는 public 또는 protected인 기본 생성자를 가져야한다. 왜냐하면 JPA는 Entity 조회 시 데이터베이스 column 값을 객체 필드에 주입해야 하는데 이때 자바에서 제공하는 Reflection API를 이용해서 column값과 Entity를 매핑하고 이떄 사용되는 Reflection API는 기본 생성자를 필수로 필요로 한다.
1-2. @NoArgsConstructor (access = AccessLevel.PROTECTED) - protected로 설정하는 이유는?
- 이번 포스팅 주제와 벗어나기 때문에 간단히만 설명하면 Spring에서는 프록시와 지연로딩이라는 개념으로 쿼리 조회에 대한 낭비를 방지한다. 이때 프록시가 상속을 통해 Entity와 동일한 프록시 객체를 생성하기 때문에 private가 아닌 자식은 접근 가능한 Protected로 생성하는 것이다. @NoArgsConstructor를 사용해서 생성자를 만들게 되면 제어자가 public으로 생성되기 때문에 굳이 외부에서 생성할 수 있는 가능성을 열어두는 것은 좋지 않다. 그래서 @NoArgsConstructor를 사용하더라도 옵션으로 생성자를 protected로 만들어주는 @NoArgsConstructor (access = AccessLevel.PROTECTED)를 사용하는 것이다.
2-2. @RequiredArgsConstructor
@RequiredArgsConstructor는 Required: 필수의 Args: 인수(파라미터) Constructor: 생성자 즉 필수로 값이 들어가야 하는 필드를 매개변수로 가지는 생성자를 만들어 준다. 필수로 값이 들어가야 한다는 것은 객체 생성 시 생성자에서 필수로 초기화 돼야 하는, 제어자가 final로 선언된 필드 혹은 @NotNull 어노테이션이 붙은 필드에 대해서만 초기화를 해주는 생성자를 만들어 준다. 그래서 보통 생성자를 통한 의존성 주입을 할 때 많이 사용한다.
@RequiredArgsConstructor
public class Member {
private final String name;
@NotNull
private int age;
private String phone;
//아래와 같이 생성 됨.
//phone는 생성 안됨.
public Member(String name, int age) {
this.name = name;
this.age = age;
}
}
@RequiredArgsConstructor는 오직 final, @NotNull이 붙은 필드에 대해 생성자를 생성해주고 기본 생성자는 생성하지 않는다. 기본 생성자가 필요한 상황에는 따로 생성해주거나 @NoArgsConstructor를 붙혀줘야 한다.
2-3. @AllArgsConstructor
@AllArgsConstructor는 말그대로 All:모든 Args:인수(파라미터) Constructor:생성자 즉 클래스 내의 모든 변수값을 매개변수로 가지는 생성자를 만들어준다
@AllArgsConstructor
public class Member {
private String name;
private String phone;
private int age;
//아래와 같이 생성 됨.
public Member(String name, String phone, int age) {
this.name = name;
this.phone = phone;
this.age = age;
}
}
@AllArgsConstructor는 생성자를 만들어줄 때 필드의 순서와 동일하게 만들어 주기 때문에 만약 객체를 생성할 때 값의 순서를 잘못 넣어주면 전혀 다른 값으로 변수 초기화가 일어날 수 있기 때문에 조심해줘야 한다. 별거 아니라고 생각이 들 수도 있지만 거래 관련 로직에서 값이 잘못 들어가버리면 정말 큰일이 날 수 있다.
@AllArgsConstructor
public class Account {
private int sendPrice; //입금액
private int sendPerPoint; //입금액 당 포인트
}
// 입금액 10000원, 포인트 1000원
Account account = new Accout(1000, 10000);
입금액 10000원당 1000원을 넣어주려고 했지만 1000원을 넣으면 10000원이 들어올 수도 있다(개꿀..?)
스스로 찾아보고 공부 한 내용을 기록하는 개인 공부 블로그입니다.
내용 중 틀린 부분이나 궁금한 내용은 언제든지 댓글로 남겨주세요🧐
'Backend > Spring' 카테고리의 다른 글
[Spring] Spring Bean 조회 (0) | 2023.12.22 |
---|---|
[Spring] IoC Container? DI Container와 Spring Bean이란? (0) | 2023.12.16 |
[Spring] DI(Dependency Injection)란? (0) | 2023.11.29 |
[Spring/Error][해결] java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'postDTO' available as request attribute (1) | 2023.11.03 |
[Spring/Error][해결] @%7B/signin%7D (0) | 2023.10.21 |