Lombok

업데이트:

Lombok이란 Java 라이브러리로 반복되는 getter, setter, toString 등의 반복적인 메서드 작성 코드를 줄여주는 코드 다이어트 라이브러리다. Eclipse나 IntelliJ 같은 IDE에서 자동 생성 기능을 사용하지만, 이것 역시 번거로울 뿐만 아니라 반복되는 코드로 인해 가독성이 떨어진다.

Lombok은 여러가지 어노테이션을 제공하고 이를 기반으로 반복 코드를 컴파일 과정에서 생성해주는 방식으로 동작하는 라이브러리이다. 즉, 클래스나 메서드에 어노테이션을 달아주면 실제로 컴파일된 결과물 .class 파일에는 해당 코드가 생성된다.

롬복의 단점

롬복 라이브러리는 사용이 편한만큼 주의할 점이 있다. @Data 같은 어노테이션이나 @ToString을 모든 엔티티에 붙이게 되면 서로 참조하고 있는 경우 순환 참조나 무한 재귀 호출 문제를 일으킨다. 이걸 숙지한 상태로 주의깊게 사용하면 되지만 습관적으로 엔티티나 DTO 클래스에 붙이게 되면 후에 문제가 발생할 여지가 크다.

롬복 사용법

1. build.gradle에 아래의 dependency를 추가한다.

compileOnly 'org.projectlombok:lombok'  // (1)
annotationProcessor 'org.projectlombok:lombok' // (2)

(1) : compile 때만 의존성 추가

(2) : 컴파일러에게 lombok 어노테이션 확인해달라고 요청하는 것

이렇게 의존성을 추가하면 gradle build 시 롬복 어노테이션을 컴파일하게 된다. 하지만 IntelliJ에서는 여전히 붉은 에러 표시가 나며 @Getter@AllArgsConstructor 같은 롬복 어노테이션을 인식하지 못한다.

2. IntelliJ에서 롬복을 사용하기 위해 plugin을 설치해준다.

  • Window : file > Setting > Plugins > ‘lombok’ 입력 > 설치
  • MacOS : IntelliJ IDEA > preferences > Plugins > ‘lombok’ 입력 > 설치

Untitled

현재 이미 설치된 상태라 Installed에 Lombok이 위치하고 있다.

설치 한 이후 Restart intelliJ IDEA 버튼이 나오고, intelliJ를 restart 해준다.

3. Settings > Build > Compiler > Annotation Processors로 이동하고,  Enable annotation processing을 체크해준 후, lombok을 사용하면 된다.

Untitled

롬복 어노테이션

  • Constructor
  • Getter/Setter
  • EqualsAndHashCode/ToString
  • Data
  • Builder

Constructor

  • @AllArgsConstructor
  • @RequiredArgsConstructor
  • @NoArgsConstructor

생성자는 이렇게 세 가지 어노테이션이 존재한다. 이름에서 알 수 있듯이 모든 필드를 주입 받는 생성자, 필수로 주입 받아야 하는 필드만 채우는 생성자, 기본생성자이다.

AllArgsConstructor

Untitled

이렇게 어노테이션을 설정해주면 모든 필드에 주입받는 생성자가 만들어진다.

Untitled

Untitled

이렇게 잘 작동하는 것을 볼 수 있다. (편의를 위해 잠시 @ToString을 추가한 상태)

Untitled

AllArgsConstructor 어노테이션 내부로 가보면 3개의 속성이 있다.

  • staticName default “”
  • access default {}
  • onConstructor default AccessLevel.PUBLIC

3개 중에 필요한 것만 선언하면 된다.

  1. staticname
    • static한 생성자를 만들어준다.
    • 기존 형태의 생성자는 private으로 변경
    • 이름을 설정해주고 사용하면 된다.
  2. access
    • 생성자의 접근제한자 설정
    • PUBLIC, PROTECTED, PRIVATE, PACKAGE, MODULE, NONE
    • staticname을 호출하고 access도 추가하면 static 생성자에 대한 접근 권한 설정으로 변경
    • access만 호출하면 기존 생성자에 대한 접근제한자 설정
  3. onConstructor
  • 생성자 위에 어노테이션을 달아준다. 아래 이미지와 동일한 효과

Untitled

RequiredArgsConstructor

Untitled

필수인 필드는 @NonNull 또는 final 선언을 통해 정해줄 수 있다.

Untitled

Untitled

이렇게 주입받은 필드를 제외한 나머지는 기본값이나 null로 들어가게 된다.

속성은 @AllArgsConstructor와 동일.

NoArgsConstructor

Untitled

기본생성자이다. 마찬가지로 속성은 동일.

Getter/Setter

Untitled

이름 그대로 getter와 setter를 추가해주는 어노테이션이다.

Untitled

Untitled

set과 get이 잘 이루어졌다.

Getter에는 3가지 속성이 있다.

  • value default AccessLevel.PUBLIC
  • onMethod default {}
  • lazy default false

value는 생성자의 access와 동일한 접근제한자 설정이다.

onMethod는 getter 메소드에 어노테이션을 설정하는 속성이다.

Untitled

아래와 같은 Getter 메소드가 생긴다고 생각하면 된다.

Untitled

lazy는 필드의 값을 지연시키는 속성이다.

Untitled

필드에 선언해 줬을 때 사용가능하다. final선언을 한 필드여야하고 getName()을 호출했을 때 makeName 메서드를 호출한다. 기본값은 false이고 이 때는 객체 생성할 때 바로 makeName()을 호출한다.

Setter에는 onParam 속성이 있는데 생성자의 onConstructor 처럼 setter 메소드에 어노테이션을 추가한다. 아래 @Setter와 setName은 동일 코드이다.

Untitled

EqualsAndHashCode/ToString

이름 그대로 Equals와 HashCode, ToString을 선언해주는 어노테이션이다.

Untitled.png

Untitled (1).png

두 어노테이션이 공통으로 가지고 있는 속성이 많아서 묶어서 얘기해보려고 한다.

  1. exclude
    • 제외시킬 변수명 작성
     @EqualsAndHashCode(exclude = {"id", "name"})
    
  2. of
    • 포함시킬 변수명 작성
    • equals나 hashCode는 Immutable(불변) 객체를 제외하면 of로 객체를 특정할 수 있는 필드만 정해서 선언하는 것이 필수적이다. 그렇지 않다면 필드값이 바뀔때마다 hashCode가 달라져서 같은 객체인데도 다르다고 판별하게 될 것이다.
     @EqualsAndHashCode(of = {"id", "name"})
    
  3. callSuper
    • 상위 클래스의 호출 여부를 묻는 속성
  4. doNotUseGetters
    • ture로 설정하면 getter를 통해 접근하는 것이 아닌 필드에 직접 접근하게 된다.
  5. onlyExplicitlyIncluded
    • ture로 설정하면 non-static non-transient 필드들이 포함되지 않는다.

Data

대망의 @Data 어노테이션이다. getter, setter, toString, hashCode, equals, requiredArgsConstructor 등을 한번에 선언해준다. 속성으로는 staticConstructor을 가지고 있는데 생성자의 staticName과 동일한 static 생성자 네이밍 속성이라고 보면 된다.

Untitled (3).png

Untitled (2).png

getter, setter, create라는 이름의 static 생성자, equalsAndHashCode, ToString까지 모두 존재하는 것을 확인할 수 있다. 바로 위에서 말했던 것처럼 equalsAndHashCode, ToString은 속성을 정해주지 않으면 오류가 날 확률이 매우 높아지기 때문에 Data 사용도 주의해야한다.

Builder

객체 생성을 명확하고 쉽게 해준다. 각각의 필드명으로 builder를 만들어주어 값을 편하게 넣어줄 수 있는데 클래스에 선언하는 방법과 직접 생성한 생성자에 붙이는 방법이 있다.

Untitled (1).png

Untitled.png

Untitled

Untitled

결론

개인적으로 선호하는 것은 생성자와 Getter, Builder 정도이다. 그 외 것들은 에러를 만들 여지가 매우 높다고 생각하기에 규모가 작거나 혼자 하는 프로젝트에서 사용하는 게 좋을 거 같다는 생각이 들었다. 이번에 별 생각없이 쓰던 롬복 어노테이션을 한번 자세히 찾아봤다. 내부에 다양한 속성이 있어 기존에 일일히 생성해주던 디테일한 부분까지도 어노테이션으로 정리할 수 있을 거 같아 코드가 더 줄어들 여지가 있다는 것이 인상깊었다. (ex. static 생성자 네이밍. 프로젝트에선 일일히 선언해줬었다) 이외에도 다양한 어노테이션이 많으니 후에 소개해보도록 하겠다.

참고

https://free-strings.blogspot.com/2015/12/lombok.html

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=vefe&logNo=222072718782

http://wonwoo.ml/index.php/post/1607

https://javaengine.tistory.com/entry/Lombok-사용상-주의점Pitfall

댓글남기기