lombok AllArgsConstructor를 안쓰는 이유

Lombok의 @AllArgsConstructor 어노테이션은 클래스의 모든 필드를 파라미터로 받는 생성자를 자동으로 생성해주는 어노테이션입니다. 즉, 클래스에 존재하는 모든 필드를 포함한 생성자를 작성하지 않아도 Lombok이 자동으로 생성해 줍니다.

 

@AllArgsConstructor
public class NcEptR {
    private Long cKey;
    private String name;
    private Date createTime;
    private Boolean deleteFlag;
    
    // Lombok이 자동으로 아래와 같은 생성자를 생성합니다.
    // public NcEptR(Long cKey, String name, Date createTime, Boolean deleteFlag) {
    //     this.cKey = cKey;
    //     this.name = name;
    //     this.createTime = createTime;
    //     this.deleteFlag = deleteFlag;
    // }
}

 

 

@AllArgsConstructor와 @RequiredArgsConstructor에 대한 고찰

Spring 애플리케이션에서 Lombok의 @AllArgsConstructor와 @RequiredArgsConstructor는 각각 편의성을 위해 생성자를 자동으로 생성해주는 어노테이션입니다. 하지만 이 둘의 차이점과 주의할 점을 명확히 이해하고 사용하는 것이 중요합니다.

@AllArgsConstructor의 위험성

@AllArgsConstructor는 클래스의 모든 필드를 인자로 받는 생성자를 자동으로 생성합니다. 이는 초기 개발 시에는 매우 편리하지만, 다음과 같은 치명적인 문제가 발생할 수 있습니다:

  • 필드 순서에 의존적: @AllArgsConstructor가 생성하는 생성자는 필드의 순서에 의존합니다. 만약 두 필드가 같은 타입(예: String)이고 필드의 순서가 변경되었을 때, 컴파일 에러 없이 잘못된 값이 할당될 수 있습니다.
@AllArgsConstructor
public class User {
    private String firstName;
    private String lastName;
}

// 필드 순서가 변경된 경우
User user = new User("Doe", "John"); // 논리적 오류

이런식으로 논리적인 오류가 발생할 수 있습니다.

 

@RequiredArgsConstructor의 선택적 사용

@RequiredArgsConstructor는 final 필드나 @NonNull 어노테이션이 붙은 필드만을 인자로 받는 생성자를 자동으로 생성합니다. 따라서 @AllArgsConstructor와 같은 순서 문제를 해결하는 직접적인 방법은 아니지만, 다음과 같은 이유로 더 나은 선택일 수 있습니다:

  • 필수 파라미터의 인지: 개발자가 필드에 final을 붙인다는 것은 해당 필드가 반드시 초기화되어야 한다는 것을 명확하게 나타냅니다. 즉, 이 필드는 객체가 생성될 때 반드시 값이 주입되어야 하며, 개발자는 이를 인지하고 설계하게 됩니다. 이는 무의식적으로 모든 필드를 생성자에 넣는 @AllArgsConstructor와 달리 의도적으로 필요한 필드만 주입하게 만듭니다.
  • 스프링과의 호환성: 스프링에서는 생성자를 통해 의존성을 주입할 때, 필드 순서에 의존하지 않고 타입과 이름을 기반으로 적절한 빈을 주입합니다. 즉, 스프링의 의존성 주입(DI) 메커니즘은 필드 순서가 바뀌더라도 타입이 일치하는 빈을 찾아주기 때문에, 필드 순서 문제를 크게 걱정하지 않아도 됩니다.
@RequiredArgsConstructor
@RestController
public class UserController {
    private final UserService userService;
    private final EmailService emailService;

    // 스프링은 타입에 맞는 빈을 자동으로 주입해줍니다.
}

따라서 반드시 초기화하는 final을 추가해 서비스나 레포지토리를 주입 받아 사용하는 것이 순서에 의존하지 않고 사용하는 좋은 방법이라고 할 수 있습니다.

 

결론

 

final이 붙는 즉, 변경되지 않는 경우에는 Requried를 사용하고,

순서를 인지해서 스프링에 주입하는 경우에는 직접 만드는게 논리적 오류없이 해결할 수 있다.

'CS' 카테고리의 다른 글

DHCP 동작 과정의 대한 이해  (0) 2024.11.24
DHCP에 대한 개념 공부 해보기  (1) 2024.11.19
IP 와 Port 그리고 Socket  (0) 2024.08.08
delete method는 form-data를 못쓴다.  (0) 2024.08.07
Process 와 Thread  (0) 2024.06.10