Skip to main content

Command Palette

Search for a command to run...

[Spring] @AllArgsConstructor을 지양하는 이유

Updated
2 min read
[Spring] @AllArgsConstructor을 지양하는 이유
S

Nice to meet u :) Im Backend Developer

✍️ 작성하게 된 이유

Spring을 사용하면서 Lombok의 @AllArgsConstructor, @RequiredArgsConstructor 같은 어노테이션은 정말 편리합니다. 필드를 선언해두기만 하면, 생성자를 자동으로 만들어주기 때문입니다.

하지만 이 편의성이 설계와 유지보수 측면에서 오히려 위험이 될 수 있습니다.

이번 글에서는 @AllArgsConstructor 사용 시 발생할 수 있는 문제와 이를 대체할 수 있는 더 안전한 방법을 정리해보려 합니다.


@AllArgsConstructor란?

@AllArgsConstructor
public class User {
    private String id;
    private String name;
}

→ 위 코드처럼 클래스에 선언된 모든 필드를 파라미터로 받는 생성자를 자동으로 만들어주는 Lombok 어노테이션입니다.

그런데 왜 위험할까?

필드 순서 변경 = 치명적 버그 가능성

User user = new User("Kim", "1234"); // id에 name이 들어가고, name에 id가 들어감!

같은 타입의 필드가 여러 개일 경우, 필드 순서를 바꾸는 순간 컴파일 에러가 발생하지 않고 추후 인지하지 못한 버그가 발생할 수 있습니다. 자동으로 생성되기 때문에 추후 문제가 발생했을 때 버그를 잡기 어렵습니다.

그렇다면 @RequiredArgsConstructor는 괜찮을까?

@AllArgsConstructor와 동일한 문제를 안고 있지만 편의성을 위해 이 정도는 인지하고 사용해도 괜찮다고 합니다.

@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;
    private final EmailService emailService;
}

✅ 이유

  • final 붙이면서 필수 파라미터에 대한 인지를 하고 필드 선언

  • 필드 순서가 변경되어도 스프링이 타입과 이름에 따른 빈을 찾아 주입하기 때문에 무리 없음

  • 의존성이 명확

⚠️ 주의

  • 스프링이 관리하지 않는 사용자가 직접 만들고 사용하는 일반 객체에서는 여전히 위험 가능성 존재

  • 생성자에 들어가는 필드가 많아질 경우, 의존성 설계 재검토 필요

대안: @NoArgsConstructor@Builder를 이용하자

@NoArgsConstructor 은 기본 생성자를 자동으로 생성해줍니다. 하지만, 접근제어자를 명확하게 정의하지 않고 그대로 사용하면 의미 없는 객체 생성을 막을 수 없습니다. 따라서 @NoArgsConstructor(access = AccessLevel.PROTECTED)같이 접근제어자를 명시하여 코드의 안전성을 높이는 것이 좋습니다.

또한, 메서드 레벨에서 @Builder 를 사용하여 의미있는 객체를 생성할 수 있습니다. 필드 순서를 보장해주기 코드의 안전성이 높아집니다.

클래스 레벨에 @Builder를 붙이면 안되나?

이번 프로젝트에서 클래스에 @Builder@NoArgsConstructor를 사용했었습니다. 하지만 Lombok @Builder needs a proper constructor for this class에러가 발생하였습니다. 이를 해결하기 위해서는 @AllArgsConstructor도 같이 사용해야합니다.

에러가 발생하는 이유는 다음과 같습니다.

정리해 보면 @NoArgsConstructor어노테이션이나 다른 생성자들이 존재하지 않을 경우 전체 생성자를 자동을 생성해 주고, 기본 생성자나 다른 생성자들이 존재하면 @AllArgsConstructor을 사용해서 직접 전체 생성자를 만들어줘야 합니다.
클래스 레벨에서 @Builder경우 기본 생성자를 생성해주는 @NoArgsConstructor와 같이 사용하게 된다면 @Builder에서 제공하는 암묵적 @AllArgsConstructor이 사라지게 되어 해당 오류가 발생합니다.

따라서, @AllArgsConstructor의 위험성이 다시 나타나기 때문에 메서드 레벨에서 @Builder를 사용하는 것이 좋습니다.

참고자료

https://techjisu.tistory.com/155

혹시 @AllArgsConstructor 를 지양하시는 이유가 빌더 패턴을 사용하기 위함인가요?

https://coding789.tistory.com/324

https://marchcodig.tistory.com/285

https://resilient-923.tistory.com/418

More from this blog

[Spring] N+1문제 발생과 분석

✍️ 작성하게 된 이유 옷을 관리하는 서비스를 개발하면서 Cloth 엔티티와 그에 연관된 ClothWithAttributes, Attribute 데이터를 함께 조회하는 기능이 필요했다.그런데 연관 데이터를 조회할 때마다 쿼리가 폭발적으로 증가(N+1 문제) 하며, 성능이 급격히 저하되는 상황을 마주하게 되었다. Spring JPA의 대표적인 문제로 N+1임을 알고있었지만, 해결하는 방법은 Fetch Join밖에 몰랐다. 지연로딩되는 필드를 엔티...

Sep 17, 20256 min read
[Spring] N+1문제 발생과 분석

데이터베이스 기본 개념 정리

1️⃣ 데이터베이스(DB) & DBMS DB (Database): 일정한 규칙(스키마)에 따라 구조화되어 저장된 데이터의 집합. DBMS (Database Management System): DB를 제어/관리하는 시스템 소프트웨어. 특징: 실시간 접근 가능, 동시 공유 가능. 구조: 데이터베이스 → DBMS → 응용 프로그램 → 사용자 2️⃣ 엔티티(Entity) & 릴레이션(Relation) 엔티티: 여러 속성을 가진 "개체"...

Aug 5, 20252 min read
데이터베이스 기본 개념 정리

[Project] 날씨에 맞는 옷 추천 서비스 : 지그재그 크롤링 여정 기록 (1) ChromeDriver를 EC2에 설치하기

✍️ 작성하게 된 이유 무신사, 29cm는 Jsoup으로 충분히 크롤링이 가능했기 때문에, ZigZag도 당연히 Jsoup으로 처리될 것이라 생각했다. 무신사, 29cm와 마찬가지로 필요한 데이터는 모두 <script> 태그 안에 들어있었다. 하지만… 예상은 보기 좋게 빗나갔다. 🧪 현상 ✅ 로컬 크롤링 → 정상 작동 Jsoup으로 script 태그 내에서 대표 이미지와 상품명을 잘 추출 로컬 환경에서는 아무 문제 없이 작동 ❌ A...

Jul 30, 20253 min read
[Project] 날씨에 맞는 옷 추천 서비스 : 지그재그 크롤링 여정 기록 (1) ChromeDriver를 EC2에 설치하기

[Project] 날씨에 맞는 옷 추천 프로젝트: Selenium은 정말 필요한 선택이었을까? - 크롤링 삽질 기록

✍️ 작성하게 된 이유 날씨에 따라 옷을 추천해주는 서비스를 만들면서, 사용자가 입력한 구매 링크에서 옷 정보( 대표이미지, 상품명 )를 불러오는 기능이 필요했다. 처음에 해당 페이지를 동적 페이지로 판단했고, 자연스럽게 Selenium을 도입했다. 하지만 이 결정이 과연 최선이었는지는 수많은 시행착오 끝에야 알 수 있었다. 🕸️ Selenium을 선택한 이유 동적 페이지는 Jsoup으로 크롤링이 어렵다는 인식으로 처음부터 Selenium을 ...

Jul 28, 20254 min read
[Project] 날씨에 맞는 옷 추천 프로젝트: Selenium은 정말 필요한 선택이었을까? - 크롤링 삽질 기록

Soyulia's Blog

49 posts