스프링 부트 자동 생성자 올바르게 사용하기

김준태·2023년 6월 21일
0

스프링

목록 보기
1/1
post-thumbnail

생성자 자동 생성자 올바르게 사용하기

  • 우선 Lombok에서 제공하는 어노테이션 3개를 떠올릴 수 있다.

@NoArgsConstructor

  • 매개변수가 없는 기본 생성자를 자동으로 생성
  • JPA에서는 프록시를 생성을 위해서 기본 생성자를 반드시 하나를 생성해야한다.
@NoArgsConstructor
public class Example {
    private String field;
}public class Example {
    private String field;

    public Example() {
    }
}

@AllArgsConstructor

  • 모든 필드를 매개변수로 받는 생성자를 자동으로 생성
  • 매우 편리하게 생성자를 만들어주지만, 별 생각없이 작성한 코드가 치명적인 버그를 만들어낼 수도 있다.
@AllArgsConstructor
public class Example {
    private String field;
}public class Example {
    private String field;

    public Example(String field) {
        this.field = field;
    }
}

@RequiredArgsConstructor

  • 필드 중 초기값이 할당되지 않은 final 필드, 그리고 @NonNull 어노테이션으로 표시된 필드를 매개변수로 받는 생성자를 자동으로 생성
@RequiredArgsConstructor
public class Example {
    private final String field1;
    @NonNull
    private String field2;
}public class Example {
    private final String field1;
    private String field2;

    public Example(String field1, String field2) {
        if (field2 == null) {
          throw new NullPointerException("field2 is marked non-null but is null");
        }
        this.field1 = field1;
        this.field2 = field2;
    }
}

결론

  • 물론 편하게 위 생성자를 사용해서 생성자를 만드는것도 좋지만, 사소한 객체 생성부터 고민해보는 것이 클린 코드, 유지 보수를 고려한 좋은 코드를 만들 수 있는 습관이 된다고 한다.
  • 최대한 @RequiredArgsConstructor, @AllArgsConstructor사용을 지양하며 @NoArgsConstructor에 생성자의 접근레벨을 PROTECTED로 해준뒤 생성자를 생성할경우 @Builder를 붙여주는 방향으로 해야겠다.
// refactor 전 코드 
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReviewImage {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long Id;
    @ManyToOne
    private Review review;
    @NotNull
    private String imageUrl;
}

// refactor 후 코드
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class CommentImage {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long Id;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "comment_id")
    private Comment comment;
    @NotNull
    private String imageUrl;

    @Builder
    public CommentImage(Comment comment, String imageUrl) {
        this.comment = comment;
        this.imageUrl = imageUrl;
    }
}

0개의 댓글