본문 바로가기
개발

[Lombok] @Builder와 @SuperBuilder (1탄)

by angeloper 2023. 6. 27.
반응형

안녕하세요.

오늘은 금일 개발을 하면서 기억하고 싶은 부분 또한, 명확하게 사용방법을 알기 위해서 기록을 합니다.

 

먼저, 제목에서와 같이 Lombok이라는 것은 설명해야 할 것 같은데요. Lombok의 공식사이트(https://projectlombok.org/)에서는 Project Lombok이라고 되어 있으며, 다음과 같이 설명하고 있습니다.

Project Lombok은 편집기 및 빌드 도구에 자동으로 연결되어 Java를 향상하는 Java 라이브러리입니다.
다른 getter 또는 equals 메소드를 다시 작성하지 마십시오. 하나의 주석으로 클래스에 완전한 기능을 갖춘 빌더, 로깅 변수 자동화 등이 있습니다.

 

다만, 저의 경우에는 편하게 Lombok이라고 칭하고 있으며, Spring Boot Project를 생성하는 사이트(https://start.spring.io)에서도 Lombok이라는 명칭으로 종속성을 추가할 수 있으며, Lombok은 Java 클래스에서 상용구 코드를 줄이는 데 도움이 되는 Java 라이브러리 "상용구 코드를 줄이는 도움이 되는 Java 주석 라이브러리" 라고 설명하고 있습니다.

 

Lombok은 컴파일 중에 반복적이고 일상적인 코드를 자동으로 생성하는 일련의 주석을 제공하여, 작성해야 하는 코드의 양을 줄여 코드 가독성과 유지 관리성을 향상하고 있다고 생각합니다.

 

Lombok의 주요 메서드는 @Getter, @Setter, @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode, @Slf4j, @Builder 등이 존재하는데요. 그중에 @Builder에 대해서 설명을 하려고 합니다.

 

왜냐하면, 금일 Builder를 사용하다가 문제가 발생하였기 때문이죠! 그럼 Builder에 대해서 알아봅시다.

 

@Builder와 @SuperBuilder는 Java 클래스에 대한 빌더 클래스 생성 프로세스를 단순화 하기 위해서 사용됩니다.

그리고, @Builder와 @SuperBuilder는 다음과 같은 차이점을 가지고 있습니다.

 

- @Builder : Java Class에 대한 빌더 클래스를 생성하는데 사용합니다.

- @SuperBuilder : @Builder의 확장이며, 상속 계층 구조의 클래스에 대한 추가기능을 제공합니다. 이를 클래스에 적용하면 현재 클래스의 필드와 상위 클래스의 필드를 설정하기 위한 메서드를 포함하는 빌더를 생성합니다.

 

요약하자면, @Builder는 단일 클래스에 대한 빌더를 생성, @SuperBuilder는 상속 계층 구조에서 현재 클래스와 부모 클래스 모두의 필드를 포함하는 빌더를 생성합니다.

 

한번 개발 소스로 한번 확인하시죠. 만약 다음과 같은 코드가 존재한다고 합시다.

package com.example.builder.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Person {
    private Long id;
    private String name;
    private int age;
}
--------------------------------------------------
package com.example.builder.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Person {
    private String schoolName;
    private String schoolYear;
}

이 경우에는 다음과 같은 에러가 발생됩니다.

해석을 그대로 하자면, 학생 Class에 존재하는 Builder함수는 사람 Class에 존재하는 Builder 함수를 숨길수 없으며, return Type이 호환되지 않는 말이었습니다. 이렇게는 명확히 무엇을 뜻하는 것인지 모르기 때문에 더 찾아본 결과, 부모의 반환 유형은 하위 클래스만 반환할 수 있는데, 그렇지 않기 때문인 듯 보입니다.

 

builder() in Student cannot hide builder() in Person
@Builder
^
 return type StudentBuilder is not compatible with PersonBuilder

 

이를 해결하기 위해서, Lombok에서는 1.18.2 버젼에서 @SuperBuilder를 실험적으로 도입하였으며, 부모와 자식 모두 @SuperBuilder로 표기하여 해결할 수 있었습니다.

package com.example.builder.entity;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class Person {
    private Long id;
    private String name;
    private int age;
}
--------------------------------------------------------------
package com.example.builder.entity;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Person {
    private String schoolName;
    private String schoolYear;
}

이를 더 자세히 보기 위해서는 Build 된 class 파일을 보시면 좋을 것으로 생각됩니다. class 파일을 보시면 @SuperBuilder를 사용한 부분이 어떻게 처리되었는지를 확인하실 수 있습니다.

 

이 부분에 대해서, 다르게 처리도 가능할 것으로도 보입니다. 그러나, 빠르고 편리하게 처리하기 위해 @SuperBuilder로 개선이 되었으므로 있는 것을 활용하여 빠르게 처리하는 것도 하나의 중요한 점이라고 생각됩니다.

 

그럼 오늘도 즐거운 개발 되시길 바라며...

반응형