본문 바로가기
자바,스프링 - Java,Spring Framework

Java Library - Lombok이란, Lombok 사용법, @Data, @Getter, @Builder, Lombok 장점, Lombok 단점

by devscb 2023. 3. 4.
반응형



Java Library - Lombok이란, Lombok 사용법, @Data, @Getter, @Builder, Lombok 장점, Lombok 단점



Java Library - Lombok이란?


프로젝트 롬복은 표준판 코드를 최소화하거나 제거하는 데 사용되는 인기 있고 널리 사용되는 자바 라이브러리입니다.
개발 시간과 노력을 절약해주며,
annotation(어노테이션, @)을 사용하여 소스 코드 가독성을 증가시켜줍니다.


Lombok 뜻


롬복의 뜻은 인도네시아 서누사텡가라 지방에 있는 섬입니다.
Java 프로그래밍언어가 인도네시아 섬 자바에 따온 만큼, 인도네시아 관련되어서 이름을 이렇게 지은거 같습니다.
이 섬의 위치는 아래와 같습니다.
서쪽으로는 롬복 해협이 발리에서, 동쪽으로는 숨바와 사이에 알라스 해협이 분리되면서 레서 순다 제도의 일부를 이룹니다.




Lombok 사용법 - Lombok 설치


Lombok 설치를 하기 위해서 gradle또는 maven을 활용할 수 있습니다.
maven 사용시 pom.xml의 dependency에 아래 내용을 넣어줍니다.


<dependencies>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.24</version>
  <scope>provided</scope>
</dependency>
</dependencies>




gradle 사용시 build.gradle에 아래와 같이 dependency를 추가해줍니다.


repositories {
mavenCentral()
}

dependencies {
compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'

testCompileOnly 'org.projectlombok:lombok:1.18.24'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'
}

 

eclipse의 경우, eclipse.ini 파일에, 아래 내용을 입력해주도록 합니다.

-javaagent:[lombok 경로]

 

ex)

-javaagent:D:\program_files\eclipse-jee-2024-06-R-win32-x86_64\lombok.jar

 

 


lombok에 대한 각 버전별 artifact는 아래 주소에서 확인 및 다운로드 받을 수 있습니다.
https://mvnrepository.com/artifact/org.projectlombok/lombok


Lombok 사용법 - @Getter, @Setter


일반적인 클래스를 만들때, 클래스명 상단에 @Getter와 @Setter를 사용하면
빌드타임에 getter와 setter가 만들어 집니다.
예를 들어, 아래 코드를 고쳐보겠습니다.  


public class GetterSetterExample {
  private int age = 10;
  private String name;
  
  public int getAge() {
    return age;
  }
  
  public void setAge(int age) {
    this.age = age;
  }
  
  protected void setName(String name) {
    this.name = name;
  }
}


위 코드를 Lombok 의 Getter, Setter annotation(어노테이션)을 사용하면 아래와 같이 작성할 수 있습니다.


@Getter
@Setter
public class GetterSetterExample {
  private int age = 10;
  private String name;
}


빌드타임에 age와 name에 대해 자동으로 생성이 됩니다.
아래와 같이 특정 필드에 대해서 사용도 가능합니다.


public class GetterSetterExample {
@Getter
private int age = 10;
private String name;
}



이처럼 Lombok은 annotation(@)을 사용하여 코드를 짧게 작성하도록 도와주어
가독성을 향상시키도록 해주는 역할을 합니다.
Lombok의 주요 annotation을 좀 더 살펴보겠습니다.

Lombok 사용법 - @ToString()



@ToString을 사용하면 toString() 메소드를 생성하는데 도움을 줍니다.
디버깅시 각각의 필드값을 쉽게 확인할 수 있도록 도움을 줍니다.

또한, 클래스 안의 필드에 @ToString.Exclude를 사용하면 toString()에 제외할 인자를 설정할 수 있습니다.

예를 들어 아래 코드와 같이 class에 @ToString 어노테이션을 써주고,
name에는 ToString.Exclude를 해줘봅시다.


@ToString
public class ToStringExample {
private String id = 12345;
@ToString.Exclude
private String name = "test";
private Integer[] ids = {54321, 54321};
}



그러면 아래처럼 name은 생략되고,
ToStringExample 클래스에 대한 필드값들을 쉽게 확인할 수 있도록
빌드시 toString() 함수가 생성되어집니다.


public class ToStringExample {
private String id = 12345;
@ToString.Exclude
private String name = "test";
private Integer[] ids = {54321, 54321};

public String toString(){
  return "ToStringExample(id=12345, ids=[54321, 54321])";
}
}




Lombok 사용법 - 생성자 관련


생성자 관련된 Lombok의 annotation은 아래와 같은 것들이 있습니다.
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor


@NoArgsConstructor 는 말그대로 파라미터가 없는 기본 생성자를 만들어줍니다.


@NoArgsConstructor
  public static class NoArgsExample {
private String field;
  }


위와 같은 코드를 아래와 같이 컴파일해줍니다.


@NoArgsConstructor
  public static class NoArgsExample {
public NoArgsExample(){}
private String field;
  }


NoArgsConstructor annotation 을 쓸때와 아닐때의 코드수는 거의 비슷하다고 볼 수 있을거 같습니다.



다음으로, @AllArgsConstructor는 말 그대로 필드의 모든 파라미터를 사용한 생성자를 만드는 어노테이션입니다.
예를들어 아래와 같은 코드를 봅시다.


@AllArgsConstructor
public class AllArgsConstructor {
private String id ;
private String name;
private Integer[] ids ;
}


위 코드는 아래와 같이 컴파일 됩니다.
필드수가 많을 수록 유용하게 쓸 수 있으며,
POJO를 사용하는 spring framework 의 model 클래스 작성시 굉장히 편리하게 사용될 수 있습니다.



public class AllArgsConstructor {
public AllArgsConstructor(String id, String name, Integer[] ids){
  this.id = id;
  this.name = name;
  this.ids = ids;
}
private String id ;
private String name;
private Integer[] ids ;

}



@RequiredArgsConstructor 의 경우는 @NonNull 로 되어있는 필드나,
초기화가 안된 final 필드에 대한 parameter로 받는 생성자를 만들어 냅니다.

예를 들어 아래 코드를 살펴봅시다.
1) id는 final 이 아니니, 포함되지 않습니다.
2) username은 @NonNull이 있으므로 포함됩니다.
3) status는 final이고 초기화되지 않았기에 포함됩니다.
4) value 는 final이나, 초기화가 이미 되었기에 포함되지 않습니다.


@RequiredArgsConstructor
public class RequiredArgsDemo1 {
  private Long id;
  @NonNull
  private String username;
  private final boolean status;
  private final boolean value = true;
}


따라서 위 코드는 아래와 같이 컴파일됩니다.


public class RequiredArgsDemo1 {
  private Long id;
  @NonNull
  private String username;
  private final boolean status;
  private final boolean value = true;
  
  public RequiredArgsDemo1(
      @NonNull final String username,
      final boolean status
      ) {
    this.username = username;
    this.status = status;
  }
}





Lombok 사용법 - @Data  


@Data는 아래 lombok의 annotation들을 한꺼번에 적용시키는 annotation입니다.

@Getter
@Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode


@Data
public class User2 {
  private Long id;
  private String username;
}


는 아래 코드와 동일합니다.


@Getter @Setter
@RequiredArgsConstructor
@ToString
@EqualsAndHashCode
public class User2 {
  private Long id;
  private String username;
}



lombok이 없다면 아래와 같이 무지막지하게 긴 코드를 작성해야합니다.
정말로 강력한 어노테이션이라 볼 수 있습니다.


public class User2 {
  private Long id;
  private String username;
  public User2() {
  }
  public Long getId() {
    return this.id;
  }
  public String getUsername() {
    return this.username;
  }
  public void setId(final Long id) {
    this.id = id;
  }
  public void setUsername(final String username) {
    this.username = username;
  }
  @Override
  public boolean equals(final Object o) {
    if (o == this)
      return true;
    if (!(o instanceof User2))
      return false;
    final User2 other = (User2) o;
    if (!other.canEqual((Object) this))
      return false;
    final Object this$id = this.getId();
    final Object other$id = other.getId();
    if (this$id == null ? other$id != null : !this$id.equals(other$id))
      return false;
    final Object this$username = this.getUsername();
    final Object other$username = other.getUsername();
    if (this$username == null ? other$username != null : !this$username.equals(other$username))
      return false;
    return true;
  }
  protected boolean canEqual(final Object other) {
    return other instanceof User2;
  }
  @Override
  public int hashCode() {
    final int PRIME = 59;
    int result = 1;
    final Object $id = this.getId();
    result = result * PRIME + ($id == null ? 43 : $id.hashCode());
    final Object $username = this.getUsername();
    result = result * PRIME + ($username == null ? 43 : $username.hashCode());
    return result;
  }
  @Override
  public String toString() {
    return "User2(id=" + this.getId() + ", username=" + this.getUsername() + ")";
  }
}




Lombok 사용법 - @Builder


@Builder는 클래스에 빌더 패턴을 적용할 수 있게 해주는 annotation입니다.


@Builder
public class BuilderExample {
  private String name;
  private int age;
}


위 코드는 아래 코드와 같습니다.
코드수를 획기적으로 줄여 빌더패턴 코드를 만들어주게 됩니다.


public class BuilderExample {
  private String name;
  private int age;
  
  BuilderExample(String name, int age) {
this.name = name;
    this.age = age;
    this.occupations = occupations;
  }
  

  public static BuilderExampleBuilder builder() {
    return new BuilderExampleBuilder();
  }
  
  public static class BuilderExampleBuilder {
    private String name;
    private int age;
    
    BuilderExampleBuilder() {
    }
  
    
    public BuilderExampleBuilder name(String name) {
      this.name = name;
      return this;
    }
    
    public BuilderExampleBuilder age(int age) {
      this.age = age;
      return this;
    }
    

    public BuilderExample build() {
      return new BuilderExample(name, age);
    }
    
    @java.lang.Override
    public String toString() {
      return "BuilderExample.BuilderExampleBuilder("name = " + this.name + ", age = " + this.age + ")";
    }
  }
}



총평


이제까지 lombok을 쓰면 얼마나 코드를 생산성있게 짧게 작성할 수 있는지 확인할 수 있었습니다.
하지만 lombok에 대한 단점도 있습니다.
예를 들어 개발자가 원하지 않는 의도를 행하도록 하는 부분이 있을 수 있습니다.
@Builder 에서는 초기화하고 싶지 않은 필드가 null로 초기화 되는 경우가 있고,
@toString에서는 두 클래스가 서로 참조할 때 순환참조하여 stackoverflow가 나타나는 경우가 있으며,
@toString을 포함하는 @Data에서도 순환참조 문제가 발생하는 등 여러 문제점이 발생할 수 있습니다.
따라서 lombok을 사용할 때는 각 어노테이션이 생성하는 코드를 확실히 이해하고 사용하는것이 좋습니다.
개인적으로는 @Getter, @Setter, @AllArgsConstructor 정도로만 사용하면 협업시에도
다른 개발자들이 잘 헷갈리지 않고 좋은 코드를 만들어 낼 수 있지 않을까 싶습니다.
기회가 된다면 lombok 사용시 side effect에 대해서도 상세히 다뤄볼 수 있도록 하겠습니다.

#롬복,#java,#lombok,#@Data,#@AllArgsConstructor,#@Getter,#@Setter,#@ToString,#@NoArgsConstructor,#@RequiredArgsConstructor

https://devscb.com/post/151

 

Java Library - What is Lombok, how to use Lombok, @Data, @Getter, @Builder, Lombok advantages, Lombok disadvantages

Java Library - What is Lombok, how to use Lombok, @Data, @Getter, @Builder, Lombok advantages, Lombok disadvantages Java Library - What is Lombok?Project Lombok is a popular and widely used Java libr

devscb.com

 

728x90
반응형

댓글