Lombok 알아보기

gryoh·2022년 8월 18일
0

Lombok이란

Lombok(롬복)은 여러 어노테이션을 제공하는 라이브러리입니다 Java로 개발할 때 반복되는 getter/setter 등의 반복을 줄여주는 코드 다이어트 라이브러리입니다.

이를 기반으로 어노테이션을 사용하면 작성하는 소스 상엔 안보이지만 컴파일러 과정에서 컴파일된 결과물(.class)에는 getter,setter 등 생성됩니다.


lombok사용 전과 후의 소스코드입니다.

import java.time.LocalDateTime;
import java.util.Objects;

public class ProductModel {
private String productNo;
private String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;

    public ProductModel(String productNo, String productName, String productType, String deliveryType, int stock, LocalDateTime regDttm, LocalDateTime modiDttm) {
        this.productNo = productNo;
        this.productName = productName;
        this.productType = productType;
        this.deliveryType = deliveryType;
        this.stock = stock;
        this.regDttm = regDttm;
        this.modiDttm = modiDttm;
    }

    public String getProductNo() {
        return productNo;
    }

    public void setProductNo(String productNo) {
        this.productNo = productNo;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductType() {
        return productType;
    }

    public void setProductType(String productType) {
        this.productType = productType;
    }

    public String getDeliveryType() {
        return deliveryType;
    }

    public void setDeliveryType(String deliveryType) {
        this.deliveryType = deliveryType;
    }

    public int getStock() {
        return stock;
    }

    public void setStock(int stock) {
        this.stock = stock;
    }

    public LocalDateTime getRegDttm() {
        return regDttm;
    }

    public void setRegDttm(LocalDateTime regDttm) {
        this.regDttm = regDttm;
    }

    public LocalDateTime getModiDttm() {
        return modiDttm;
    }

    public void setModiDttm(LocalDateTime modiDttm) {
        this.modiDttm = modiDttm;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ProductModel that = (ProductModel) o;
        return stock == that.stock &&
                Objects.equals(productNo, that.productNo) &&
                Objects.equals(productName, that.productName) &&
                Objects.equals(productType, that.productType) &&
                Objects.equals(deliveryType, that.deliveryType) &&
                Objects.equals(regDttm, that.regDttm) &&
                Objects.equals(modiDttm, that.modiDttm);
    }

    @Override
    public int hashCode() {
        return Objects.hash(productNo, productName, productType, deliveryType, stock, regDttm, modiDttm);
    }

    @Override
    public String toString() {
        return "ProductModel{" +
                "productNo='" + productNo + '\'' +
                ", productName='" + productName + '\'' +
                ", productType='" + productType + '\'' +
                ", deliveryType='" + deliveryType + '\'' +
                ", stock=" + stock +
                ", regDttm=" + regDttm +
                ", modiDttm=" + modiDttm +
                '}';
    }
}
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public class ProductModel {
    private String productNo;
    private String productName;
    private String productType;
    private String deliveryType;
    private int stock;
    private LocalDateTime regDttm;
    private LocalDateTime modiDttm;
}

확연히 코드가 줄어든 것을 볼 수 있습니다. annotation 5개가 부담스럽다면 @Data로 한번에 처리할 수 있습니다. 자세한 건 아래에서 더 다룰 예정입니다.


Lombok의 장점과 주의사항

장점

  • 어노테이션 기반의 코드 자동 생성을 통한 생산성 향상
  • 반복되는 코드 다이어트를 통한 가독성 및 유지보수성 향상
  • Getter, Setter 외에 빌더 패턴이나 로그 생성 등 다양한 방면으로 활용 가능

주의사항

  • 모든 팀원이 lombok을 활용해야함(선지식 필요)

Lombok 세팅

1.lombok 다운&설치 -> 2.dependency추가 -> 3.lombok사용


1. lombok 다운&설치

#eclipse나 sts를 사용하는 경우

#intellij를 사용 하는 경우

  • marketplace에서 install한다.

2. dependency추가

Maven 사용 - pom.xml에 추가

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.4</version>
    <scope>provided</scope>
</dependency>

Gradle 사용 - build.gradle에 추가

// https://mvnrepository.com/artifact/org.projectlombok/lombok
provided group: 'org.projectlombok', name: 'lombok', version: '1.18.4'

3. lombok사용

intellij의 경우 아래와 같이 추가 설정을 해줘야합니다.


Annotation 종류와 설명

[ @Getter @Setter ]

Lombok에서 가장 자주 활용하는 어노테이션입니다. @Getter와 @Setter를 클래스 이름 위에 적용시키면 모든 변수들에 적용이 가능하고, 변수 이름 위에 적용시키면 해당 변수들만 적용 가능합니다.

@Getter와 @Setter를 활용한 예제는 아래와 같습니다.

@Getter
public class ProductModel {
   @Setter
   private String productNo;
   private String productName;
   private String productType;
   private String deliveryType;
   private int stock;
   private LocalDateTime regDttm;
   private LocalDateTime modiDttm;
}

[ @AllArgsConstructor ]

@AllArgsConstructor는 모든 변수를 사용하는 생성자를 자동완성 시켜주는 어노테이션입니다.

@AllArgsConstructor를 활용한 예제는 아래와 같습니다.

@AllArgsConstructor
public class ProductModel {
private String productNo;
private String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;

    /* @AllArgsConstructor를 사용함으로써 아래 소스가 자동 생성됨
    public ProductModel(String productNo, String productName, String productType, String deliveryType, int stock, LocalDateTime regDttm, LocalDateTime modiDttm) {
        this.productNo = productNo;
        this.productName = productName;
        this.productType = productType;
        this.deliveryType = deliveryType;
        this.stock = stock;
        this.regDttm = regDttm;
        this.modiDttm = modiDttm;
    }
    */
}

[ @NoArgsConstructor ]

@NoArgsConstructor는 어떠한 변수도 사용하지 않는 기본 생성자를 자동완성 시켜주는 어노테이션입니다.

@NoArgsConstructor를 활용한 예제는 아래와 같습니다.

@NoArgsConstructor
public class ProductModel {
private String productNo;
private String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;

    /* @NoArgsConstructor 사용함으로써 아래 소스가 자동 생성됨
    public ProductModel(){
        
    }
    */
}

[ @RequiredArgsConstructor ]

@RequiredArgsConstructor는 특정 변수만을 활용하는 생성자를 자동완성 시켜주는 어노테이션입니다. 생성자의 인자로 추가할 변수에 @NonNull 어노테이션을 붙여서 해당 변수를 생성자의 인자로 추가할 수 있습니다. 아니면 해당 변수를 final로 선언해도 의존성을 주입받을 수 있습니다.

@RequiredArgsConstructor를 활용한 예제는 아래와 같습니다

@RequiredArgsConstructor
public class ProductModel {
@NonNull
private String productNo;
private final String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;

    /* @RequiredArgsConstructor 사용함으로써 아래 소스가 자동 생성됨
    public ProductModel(String productNo, String productName) {
        this.productNo = productNo;
        this.productName = productName;
    }
}

[ @EqualsAndHashCode ]

@EqualsAndHashCode 어노테이션을 활용하면 클래스에 대한 equals 함수와 hashCode 함수를 자동으로 생성해줍니다. 만약 서로 다른 두 객체에서 특정 변수의 이름이 똑같은 경우 같은 객체로 판단을 하고 싶다면 아래와 같이 해줄 수 있습니다.

@EqualsAndHashCode를 활용한 예제는 아래와 같습니다

@RequiredArgsConstructor
@EqualsAndHashCode(of = {"productNo", "productName"}, callSuper = false)
public class ProductModel {
@NonNull
private String productNo;

    @NonNull
    private String productName;
    
    private String productType;
    private String deliveryType;
    private int stock;
    private LocalDateTime regDttm;
    private LocalDateTime modiDttm;
}

public static void main(String[] args) {
ProductModel product1 = new ProductModel("a111", "바나나");
ProductModel product2 = new ProductModel("a111", "바나나");
ProductModel product3 = new ProductModel("a222", "바나나");

    // productNo과 productName이 모두 같기 때문에 같다고 판단
    System.out.println(product1.equals(product2));  //true

    // productNo은 같지만 productName이 다르기 때문에 다르다고 판단
    System.out.println(product1.equals(product3));  //false
}

[ @ToString ]

@ToString 어노테이션을 활용하면 클래스의 변수들을 기반으로 ToString 메소드를 자동으로 완성시켜 줍니다. 출력을 원하지 않는 변수에 @ToString.Exclude 어노테이션을 붙여주면 출력을 제외할 수 있습니다. 또한 상위 클래스에 대해도 toString을 적용시키고자 한다면 상위 클래스에 @ToString(callSuper = true) 를 적용시키면 됩니다.

@ToString를 활용한 예제는 아래와 같습니다

@ToString
@AllArgsConstructor
public class ProductModel {
private String productNo;
private String productName;

    @ToString.Exclude
    private String productType;

    private String deliveryType;
    private int stock;
    private LocalDateTime regDttm;
    private LocalDateTime modiDttm;
}

public static void main(String[] args) {
ProductModel product = new ProductModel("a111", "바나나", "일반상품", "일반택배", 10, LocalDateTime.now(), LocalDateTime.now());

    System.out.println(product.toString());
    //결과 : ProductModel(productNo=a111, productName=바나나, deliveryType=일반택배, stock=10, regDttm=2021-05-23T17:45:20.270, modiDttm=2021-05-23T17:45:20.271)
    //@ToString.Exclude 된건 제외하고 출력
}

[ @Data ]

@Data 어노테이션을 활용하면 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor를 자동완성 시켜줍니다. 실무에서는 너무 무겁고 객체의 안정성을 지키기 때문에 @Data의 활용을 지양합니다.


[ @Builder ]

@Builder 어노테이션을 활용하면 해당 클래스의 객체의 생성에 Builder패턴을 적용시켜줍니다. 모든 변수들에 대해 build하기를 원한다면 클래스 위에 @Builder를 붙이면 되지만, 특정 변수만을 build하기 원한다면 생성자를 작성하고 그 위에 @Builder 어노테이션을 붙여주면 됩니다.

@Builder를 활용한 예제는 아래와 같습니다

모든 변수에 적용예시

@Builder
public class ProductModel {
private String productNo;
private String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;
}

public static void main(String[] args) {
//ProductModel product = new ProductModel("a111", "바나나", "일반상품", "일반택배", 10, LocalDateTime.now(), LocalDateTime.now());

    ProductModel product = ProductModel.builder()
                                        .productNo("a111")
                                        .productName("바나나")
                                        .productType("일반상품")
                                        .deliveryType("일반택배")
                                        .stock(10)
                                        .regDttm(LocalDateTime.now())
                                        .modiDttm(LocalDateTime.now())
                                        .build();
}

특정 변수에만 적용예시

public class ProductModel {
private String productNo;
private String productName;
private String productType;
private String deliveryType;
private int stock;
private LocalDateTime regDttm;
private LocalDateTime modiDttm;

    @Builder
    public ProductModel(String productNo, String productName){
        this.productNo = productNo;
        this.productName = productName;
    }
}

public static void main(String[] args) {
ProductModel product = ProductModel.builder()
.productNo("a111")
.productName("바나나")
.build();
}

[ @Log 관련 어노테이션 ]

@Log4j2와 같은 어노테이션을 활용하면 해당 클래스의 로그 클래스를 자동 완성 시켜줍니다 @Log 관련 어노테이션을 활용한 예제는 아래와 같습니다.

@RestController
@RequestMapping(value = "/product")
@Log4j2
public class ProductController {

    @GetMapping(value = "/productList") 
    private ResponseEntity log(){ 
        log.error("에러 발생"); 
        return ResponseEntity.ok().build(); 
    } 
}

결론
Lombok은 많은 개발자들이 사용하고 시간 낭비를 줄여주는 정말 소중한 라이브러리이지만 그만큼 조심해야 될 부분도 많다. Lombok이 어떻게 이런 고민을 해결하는지 살펴보고 실제로 사용해보면 좋을 것 같다!

0개의 댓글