[Lombok] @Builder, DTO 접근제한자 적절한 설정 방법

2025. 3. 11. 07:40·Spring
728x90
반응형
SMALL

@AllArgsConstructor 및 @NoArgsConstructor의 접근 제한 설정 방법

 

MSA(Microservices Architecture) 환경에서는 각 서비스가 독립적으로 동작하며, 데이터 및 객체의 무분별한 생성 및 변경을 방지하는 것이 중요하다. 따라서 @AllArgsConstructor 및 @NoArgsConstructor의 접근 제한자를 적절히 설정하여 객체의 생성 및 변경을 제어해야 한다.

 


1. @AllArgsConstructor (모든 필드를 포함하는 생성자)

@AllArgsConstructor(access = AccessLevel.PROTECTED)

설정 이유

1. 엔티티 객체의 직접적인 변경 방지

• 엔티티는 무분별하게 생성되거나 수정되어서는 안 되므로 **protected**로 설정하여 내부에서만 사용할 수 있도록 제한.

2. Spring Data JPA 및 ORM 사용을 고려

• JPA에서는 엔티티를 조회할 때 프록시 객체를 생성하는데, public 생성자가 없으면 객체를 생성할 수 없다.

• 하지만 외부에서 직접 엔티티를 생성하는 것은 지양해야 하므로 protected 수준으로 접근을 제한.

 

📌 적용 예시

@Getter
@Entity
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int price;
}

🛠 사용 예

// 잘못된 사용 (제한된 생성자 호출 불가)
// Product product = new Product(1L, "스마트폰", 1000); ❌

// 올바른 사용 (팩토리 메서드 또는 빌더 사용)
Product product = Product.createProduct("스마트폰", 1000);

 

 


2. @NoArgsConstructor (기본 생성자)

@NoArgsConstructor(access = AccessLevel.PROTECTED)

 설정 이유

1. JPA의 프록시 객체 생성을 허용해야 함

• JPA에서는 기본 생성자가 필요하므로 반드시 제공해야 하지만, 외부에서 직접 호출되는 것은 막아야 함.

• 따라서 @NoArgsConstructor(access = AccessLevel.PROTECTED)를 설정하여 엔티티 외부에서는 기본 생성자를 호출할 수 없도록 제한.

2. DTO 변환 및 직렬화(Serialization) 고려

• Jackson(JSON 변환 라이브러리)이나 Kafka 메시지 처리 시 기본 생성자가 필요할 수 있음.

• 하지만 엔티티의 경우, JSON 직렬화를 위한 DTO를 따로 만들어 사용하는 것이 일반적이므로 엔티티에 public 기본 생성자를 두지 않는 것이 좋음.

 

 적용 예시

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int price;
}

🛠 사용 예

// JPA가 기본 생성자를 사용하여 객체를 생성할 수 있음 (사용자 호출은 불가능)
Product product = new Product(); // ❌ (protected라서 외부에서 직접 호출 불가)

// JPA 내부에서는 사용 가능 (Spring이 프록시 객체를 만들 때 필요)

 

 


3. DTO 및 Service에서의 객체 생성 제한

 

DTO의 경우 public 생성자 허용

• DTO는 데이터를 담는 용도이므로 제한 없이 public 생성자를 허용하는 것이 일반적이다.

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ProductDto {
    private Long id;
    private String name;
    private int price;
}

엔티티 객체의 직접 생성 방지

• 엔티티는 @AllArgsConstructor 및 @NoArgsConstructor를 protected로 제한하고,

팩토리 메서드 또는 @Builder를 이용하여 생성하는 방식이 바람직함.

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int price;

    // 객체 생성을 위한 팩토리 메서드
    public static Product createProduct(String name, int price) {
        return new Product(null, name, price);
    }
}

🛠 사용 예

Product product = Product.createProduct("스마트폰", 1000); // ✅ 올바른 사용 방식

 

 


4. @Builder와 함께 사용할 경우

 

빌더 사용 시 생성자 접근 제한 설정

• @Builder는 @AllArgsConstructor를 필요로 하지만, 엔티티가 직접 생성되는 것을 막아야 하므로 protected로 제한해야 한다.

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private int price;
}

🛠 사용 예

Product product = Product.builder()
                         .name("스마트폰")
                         .price(1000)
                         .build(); // ✅ 빌더를 통해서만 객체 생성 가능

 

 


5. 정리: MSA 환경에서 생성자 접근 제한 기준

적용 대상생성자 접근 제한 방식설정 이유

엔티티 클래스 (@Entity) @NoArgsConstructor(access = AccessLevel.PROTECTED) JPA 프록시 객체 생성을 허용하면서 외부 사용을 제한
  @AllArgsConstructor(access = AccessLevel.PROTECTED) 직접 객체 생성을 방지하고, 빌더 또는 팩토리 메서드 사용 유도
DTO 클래스 @NoArgsConstructor(access = AccessLevel.PUBLIC) JSON 변환 및 직렬화 지원
  @AllArgsConstructor(access = AccessLevel.PUBLIC) DTO의 직렬화 및 데이터 전달 용도로 사용
빌더 패턴 사용 (@Builder) @AllArgsConstructor(access = AccessLevel.PROTECTED) 직접 객체 생성을 방지하고 빌더 패턴 사용 강제
팩토리 메서드 제공 public static 메서드로 생성 객체 생성 로직을 캡슐화

 

 


결론

 

MSA 환경에서는 무분별한 객체 생성을 방지하고, 올바른 방식으로 객체를 초기화할 수 있도록 접근 제한을 설정하는 것이 중요하다.

• 엔티티 클래스(@Entity)

• @NoArgsConstructor(access = AccessLevel.PROTECTED) → JPA를 위한 기본 생성자는 허용하지만, 외부 사용은 제한.

• @AllArgsConstructor(access = AccessLevel.PROTECTED) → 직접 객체 생성을 방지.

• @Builder 활용 시 생성자 호출을 막고 빌더만 사용 가능하도록 설정.

• DTO 클래스

• public 생성자 허용 (@NoArgsConstructor, @AllArgsConstructor) → JSON 변환 및 직렬화를 위해 필요.

• 팩토리 메서드 또는 @Builder 사용 권장

• 직접 객체 생성이 필요할 경우 public static 팩토리 메서드 제공.

 

이를 통해 MSA 환경에서 객체의 일관성을 유지하고, 올바른 방식으로 객체를 관리할 수 있도록 설계하는 것이 바람직하다. 🚀

728x90
반응형
SMALL

'Spring' 카테고리의 다른 글

[Spring AOP] JDK Dynaic Proxy에서 내부호출이 안되는 이유  (0) 2025.03.11
[Spring AOP] @Transactional의 Proxy 작동 방식  (0) 2025.03.11
[Lombok] @Builder를 클래스가 아닌 메서드에 적용하는 이유  (0) 2025.03.11
[Spring/Serialization-Deserialization] Date, LocalDate, LocalDateTime 형변환 방법, 직렬화/역직렬화 문제 해결하기  (0) 2025.03.07
[Github] Yml파일 서브모듈에서 불러와서 안전하게 사용하기  (0) 2025.02.17
'Spring' 카테고리의 다른 글
  • [Spring AOP] JDK Dynaic Proxy에서 내부호출이 안되는 이유
  • [Spring AOP] @Transactional의 Proxy 작동 방식
  • [Lombok] @Builder를 클래스가 아닌 메서드에 적용하는 이유
  • [Spring/Serialization-Deserialization] Date, LocalDate, LocalDateTime 형변환 방법, 직렬화/역직렬화 문제 해결하기
공부하고 기억하는 공간
공부하고 기억하는 공간
IT 비전공자로 시작하여 훌륭한 개발자가 되기 위해 공부하고 있는 공간입니다. 틀린 내용이나 부족한 부분이 있으면 댓글로 알려주세요 바로 수정하겠습니다.
    250x250
  • 공부하고 기억하는 공간
    IT - railroad
    공부하고 기억하는 공간
  • 전체
    오늘
    어제
    • 분류 전체보기 (315)
      • 면접 준비 (36)
        • OS (6)
        • Spring Security (0)
        • Java (2)
        • DB (9)
        • Network (3)
      • ElasticSearch (2)
      • Kafka (4)
      • Spring (22)
        • Spring Cloud (7)
        • Security6 (5)
        • JPA (12)
        • 프로젝트 리팩토링 회고록 (4)
        • Logging (8)
        • Batch (2)
      • Redis (17)
        • Redis 개념 (8)
        • Redis 채팅 (5)
        • Redis 읽기쓰기 전략 (1)
      • AWS (11)
      • 리눅스 (29)
        • 리눅스 마스터 2급 (5)
        • 네트워크(기초) (7)
        • 리눅스의 이해 (6)
        • 리눅스의 설치 (2)
        • 리눅스 운영 및 관리 (6)
      • JAVA-기초 (16)
        • JAVA기본 (11)
        • Design Pattern (5)
      • JSP (27)
        • JSP 기본 개념 (10)
        • JSP (1)
      • SQL (1)
      • TIL (36)
      • 문제 풀이 (2)
        • Programmers (9)
        • 백준 문제풀이 (28)
      • JavaScript (10)
      • HTML (17)
      • Ngrinder (1)
        • Ngrinder 문서 정리 (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      Til
      리눅스마스터2급
      리눅스
      java
      자바 면접
      JavaScript
      레디스
      자바
      HTML
      CSS
      자바 반복문
      jsp기초
      JSP
      리눅스마스터2급정리
      redis 채팅
      백준
      스프링프레임워크
      자바기초
      자바 알고리즘
      프로그래머스
      Spring Data Redis
      Spring
      자바스크립트
      springsecurity
      redis
      자바 면접질문
      jsp request
      Springframework
      JS
      spring redis
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    공부하고 기억하는 공간
    [Lombok] @Builder, DTO 접근제한자 적절한 설정 방법
    상단으로

    티스토리툴바