๊ด€๋ฆฌ ๋ฉ”๋‰ด

Jin's Dev Story

[SpringBoot] Lombok ๋ณธ๋ฌธ

Web & Android/SpringBoot

[SpringBoot] Lombok

woojin._. 2023. 8. 18. 16:40

๐Ÿ’ก Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๋ฉด์„œ ๊ธฐ๊ณ„์ ์œผ๋กœ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋Š” Getter, Setter, ToString ๋“ฑ์˜ ๋ฉ”์„œ๋“œ ์ž‘์„ฑ ์ฝ”๋“œ๋ฅผ Annotation์œผ๋กœ ๋Œ€์‹ ํ•ด ์ฝ”๋“œ ๋‹ค์ด์–ดํŠธ๋ฅผ ๋„์™€์คŒ

์žฅ์ 

  • ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์ฝ”๋“œ ์ž๋™ ์ƒ์„ฑ์„ ํ†ตํ•œ ์ƒ์‚ฐ์„ฑ ์ฆ๊ฐ€
  • ์ฝ”๋“œ ๋‹ค์ด์–ดํŠธ๋ฅผ ํ†ตํ•œ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์„ฑ ์ฆ๊ฐ€

Ex>

๊ธฐ์กด ์ฝ”๋“œ

public class Car {

    private String seqNumber;
    private String id;
    private String name;

    public Car() {}

    public Car(String seqNumber, String id, String name) {
        this.seqNumber = seqNumber;
        this.id = id;
        this.name = name;
    }

    public String getSeqNumber() {
        return seqNumber;
    }

    public void setSeqNumber(String seqNumber) {
        this.seqNumber = seqNumber;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{" +
                "seqNumber='" + seqNumber + '\'' +
                ", id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

Lombok ํ™œ์šฉ ์ฝ”๋“œ

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Car {

    private String seqNumber;
    private String id;
    private String name;

}

๐Ÿ’ก Lombok์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜!!

Lombok์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” gradle์˜ dependencies์—
implementation 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok'
๋ฅผ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

  • @Getter & @Setter
    • ์‹ค์งˆ์ ์œผ๋กœ ๊ฐ€์žฅ ๋งŽ์ด ํ™œ์šฉ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.
    • @Getter : Getter ๋ฉ”์†Œ๋“œ ์ƒ์„ฑ
    • @Setter : Setter ๋ฉ”์†Œ๋“œ ์ƒ์„ฑ
    • ์–ด๋…ธํ…Œ์ด์…˜์„ ํด๋ž˜์Šค ์œ„์— ์ž‘์„ฑํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋ชจ๋“  ๋ณ€์ˆ˜์— ์ ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ณ , ๋ณ€์ˆ˜ ์ด๋ฆ„ ์œ„์— ์ž‘์„ฑํ•˜๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜์—๋งŒ ์ ์šฉ์ด ๋œ๋‹ค.
 @Getter
  public class Car {

          @Setter
          private String seqNumber;
      private String id;
      private String name;
      private String color;
      private Integer serialNumber;
      private boolean isOnSale;

  }

  /** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/

  public class Car {
      private String seqNumber;
      private String id;
      private String name;
      private String color;
      private Integer serialNumber;
      private boolean isOnSale;

      public Car() {
      }

      public String getSeqNumber() {
          return this.seqNumber;
      }

      public String getId() {
          return this.id;
      }

      public String getName() {
          return this.name;
      }

      public String getColor() {
          return this.color;
      }

      public Integer getSerialNumber() {
          return this.serialNumber;
      }

      public boolean isOnSale() {
          return this.isOnSale;
      }

      public void setSeqNumber(String seqNumber) {
          this.seqNumber = seqNumber;
      }
  }

/**

@Getter ์–ด๋…ธํ…Œ์ด์…˜์„ ํด๋ž˜์Šค ์ƒ๋‹จ์— ์ ์šฉํ•จ์œผ๋กœ์จ ๋ชจ๋“  ๋ณ€์ˆ˜์— ๋Œ€ํ•œ Getter ๋ฉ”์„œ๋“œ๊ฐ€ ์ž‘์„ฑ๋จ.
@Setter ์–ด๋…ธํ…Œ์ด์…˜์„ seqNumber ๋ณ€์ˆ˜์—๋งŒ ์ ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ณ€์ˆ˜์˜ Setter ๋ฉ”์„œ๋“œ๊ฐ€ ์ž‘์„ฑ๋จ

**/
  • @ToString
    • @ToString ์–ด๋…ธํ…Œ์ด์…˜์€ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ToString ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.
    • ์ถœ๋ ฅ์„ ์›์น˜ ์•Š๋Š” ๋ณ€์ˆ˜ ์œ„์— @ToString.Exclude ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋ฉด ์ถœ๋ ฅ์„ ์ œ์™ธํ•œ๋‹ค.
    • ๋ถ€๋ชจ ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋„ toString์„ ์ ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด @ToString(callSuper = true) ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  @ToString
  public class Car {

      private String seqNumber;
      private String id;
      private String name;
      private String color;
      private Integer serialNumber;
          @ToString.Exclude
      private boolean isOnSale;

  }

  /** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/
  public class Car {

      private String seqNumber;
      private String id;
      private String name;
      private String color;
      private Integer serialNumber;
      private boolean isOnSale;

      @Override
      public String toString() {
          return "Car{" +
                  "seqNumber='" + seqNumber + '\'' +
                  ", id='" + id + '\'' +
                  ", name='" + name + '\'' +
                  ", color='" + color + '\'' +
                  ", serialNumber=" + serialNumber
                  '}';
      }
  }
  • @Builder
    • ๋นŒ๋” ํŒจํ„ด์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.
    • builder() : ๋นŒ๋” ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
    • build() : ์‹ค์ œ ์ƒ์„ฑ์ž ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ์ฒด ์ƒ์„ฑ
  • @AllArgsConstructor & @NoArgsConstructor(access = AccessLevel.PROTECTED)
    • @AllArgsConstructor
      • ๋ชจ๋“  ํ•„๋“œ ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š” ์ƒ์„ฑ์ž ์ƒ์„ฑ
    • @NoArgsConstructor
      •  ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์—†๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž ์ƒ์„ฑ
      • @Entity ์ ์šฉ ์‹œ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋Š” ํ•„์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๋กฌ๋ณต์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•œ๋‹ค.
      • @Builder์™€ @NoArgsConstructor๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ ๋ชจ๋“  ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์—†์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String seqNumber;
    private String id;
    private String name;
    private String color;
    private Integer serialNumber;
    private boolean isOnSale;

}

/** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/

public class Car {

    private String seqNumber;
    private String id;
    private String name;
    private String color;
    private Integer serialNumber;
    private boolean isOnSale;

		public Car () {}

    public Car(String seqNumber, String id, String name, String color, Integer serialNumber, boolean isOnSale) {
        this.seqNumber = seqNumber;
        this.id = id;
        this.name = name;
        this.color = color;
        this.serialNumber = serialNumber;
        this.isOnSale = isOnSale;
    }
}

/**

@NoArgsConstructor ์ ์šฉํ•จ์œผ๋กœ์จ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์ž‘์„ฑ๋จ
@AllArgsConstructor ์ ์šฉํ•จ์œผ๋กœ์จ ๋ชจ๋“  ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ƒ์„ฑ์ž๊ฐ€ ์ž‘์„ฑ๋จ

**/
  • @RequiredArgsConstructor
    • ํŠน์ • ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ƒ์„ฑ์ž๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.
    • ์ฃผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…, ์ฆ‰ DI ์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๊ณค ํ•œ๋‹ค.
    • ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ƒ์„ฑ๋  ์ƒ์„ฑ์ž์˜ ์ธ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์กฐ๊ฑด์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
    • ๋ณ€์ˆ˜๋ฅผ final๋กœ ์„ ์–ธ
    • ๋ณ€์ˆ˜์— @NonNull ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉ
@RequiredArgsConstructor
public class Car {

    private final String seqNumber;
    private final String id;
    private String name;
    private String color;
    @NonNull
    private Integer serialNumber;
    private boolean isOnSale;

}

/** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/

public class Car {
    private final String seqNumber;
    private final String id;
    private String name;
    private String color;
    @NonNull
    private Integer serialNumber;
    private boolean isOnSale;

    public Car(String seqNumber, String id, @NonNull Integer serialNumber) {
        if (serialNumber == null) {
            throw new NullPointerException("serialNumber is marked non-null but is null");
        } else {
            this.seqNumber = seqNumber;
            this.id = id;
            this.serialNumber = serialNumber;
        }
    }
}

/**

final๋กœ ์„ ์–ธํ•˜๊ฑฐ๋‚˜ @NonNull ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋œ ๋ณ€์ˆ˜๋“ค๋งŒ์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์ž‘์„ฑ๋จ.

**/
  • @NonNull
    • ์ƒ์„ฑ์ž์—์„œ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ NPE(Null Pointer Exception)๋ฅผ ๊ฒ€์ฆํ•ด์ค€๋‹ค.
@RequiredArgsConstructor
public class Car {

    private final String seqNumber;
    @NonNull
    private final String id;
    private String name;
    private String color;
    @NonNull
    private final Integer serialNumber;
    private boolean isOnSale;

}

/** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/

public class Car {
    private final String seqNumber;
    @NonNull
    private final String id;
    private String name;
    private String color;
    @NonNull
    private final Integer serialNumber;
    private boolean isOnSale;

    public Car(String seqNumber, @NonNull String id, @NonNull Integer serialNumber) {
        if (id == null) {
            throw new NullPointerException("id is marked non-null but is null");
        } else if (serialNumber == null) {
            throw new NullPointerException("serialNumber is marked non-null but is null");
        } else {
            this.seqNumber = seqNumber;
            this.id = id;
            this.serialNumber = serialNumber;
        }
    }
}

/**

์ƒ์„ฑ์ž๋กœ Object๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, @NonNull์ด ์ ์šฉ๋œ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ Null ์ฒดํฌ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

**/
  • @Date
    • @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor๋ฅผ ์ž๋™์™„์„ฑ ์‹œ์ผœ์ค€๋‹ค.
    • ์‹ค๋ฌด์—์„œ๋Š” ๋„ˆ๋ฌด ๋ฌด๊ฒ๊ณ  ๊ฐ์ฒด์˜ ์•ˆ์ •์„ฑ์„ ์ง€ํ‚ค๊ธฐ ๋•Œ๋ฌธ์— @Data์˜ ํ™œ์šฉ์„ ์ง€์–‘ํ•œ๋‹ค.
  • @Builder
    • @Builder ์–ด๋…ธํ…Œ์ด์…˜์€ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์— Builder ํŒจํ„ด์„ ์ ์šฉ์‹œ์ผœ์ค€๋‹ค.
    • ๋ชจ๋“  ๋ณ€์ˆ˜์— ์ ์šฉ์‹œํ‚ค๋ ค๋ฉด ํด๋ž˜์Šค ์ƒ๋‹จ์— @Builder ๋ฅผ ์ ์šฉํ•˜๊ณ , ํŠน์ • ๋ณ€์ˆ˜์— ๋Œ€ํ•œ Build๋ฅผ ์›ํ•œ๋‹ค๋ฉด ์ƒ์„ฑ์ž๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ํ•ด๋‹น ์ƒ์„ฑ์ž ์œ„์— @Builder ๋ฅผ ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค.
public class Car {

    private String seqNumber;
    private String id;
    private String name;
    private String color;
    private Integer serialNumber;
    private boolean isOnSale;

    @Builder
    public Car(String seqNumber, String id, Integer serialNumber) {
        this.seqNumber = seqNumber;
        this.id = id;
        this.serialNumber = serialNumber;
    }
}

/** ์‚ฌ์šฉ ์˜ˆ์ œ **/

public class CarFactory {

    public Car initCar(String seqNumber, String id, Integer serialNumber) {
        Car car = Car.builder()
                .seqNumber(seqNumber)
                .id(id)
                .serialNumber(serialNumber)
                .build();

        return car;
    }

}

/**

@Builder ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ํ•ด๋‹น Object์— ๋Œ€ํ•ด Builder ํŒจํ„ด์ด ์ ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
step-by-step์œผ๋กœ ํ•„์š”ํ•œ ์ธ์ž๋ฅผ ์„ ํƒํ•ด์„œ addํ•˜์—ฌ ํ•œ๋ฒˆ์— ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

**/

Builder Pattern

๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ํ”ํžˆ ์‚ฌ์šฉ๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

Car car = Car.builder()
         .seqNumber(seqNumber)
         .id(id)
         .serialNumber(serialNumber)
         .build();

์žฅ์ 

  • ๊ฐ ์ธ์ž๊ฐ€ ์–ด๋–ค ์˜๋ฏธ์ธ์ง€ ํŒŒ์•…ํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • setter ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ํ•œ๋ฒˆ์— ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•จ์œผ๋กœ์จ ์ œ๊ณต ์ƒํƒœ์— ๋Œ€ํ•œ ์ผ๊ด€์„ฑ์„ ์–ป๋Š”๋‹ค.
  • ๊ฐ์ฒด ์ƒ์„ฑ ์ตœ์ข… ๋‹จ๊ณ„์ธ build() ๋‚ด๋ถ€์—์„œ ๊ฐ’์„ ๊ฒ€์ฆํ•œ๋‹ค๋˜์ง€์˜ ์ถ”๊ฐ€์ ์ธ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

  • @Log ๊ด€๋ จ ์–ด๋…ธํ…Œ์ด์…˜
    • Lombok์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€์˜ Log ์–ด๋…ธํ…Œ์ด์…˜์„ ์ œ๊ณตํ•ด์ค€๋‹ค.
    • ๋กœ๊ทธ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋กœ๊ทธ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.
@Log4j
public class Car {
    private String seqNumber;
    private String id;
    private String name;
    private String color;
    private Integer serialNumber;
    private boolean isOnSale;
}

/** ์ปดํŒŒ์ผ ์™„๋ฃŒ ์†Œ์Šค **/
public class Car {
    private static final Logger log = Logger.getLogger(Car.class);
    private String seqNumber;
    private String id;
    private String name;
    private String color;
    private Integer serialNumber;
    private boolean isOnSale;
}

/**

์ ์šฉ์‹œํ‚จ Log ์–ด๋…ธํ…Œ์ด์…˜์— ๋งž๋Š” Log ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

**/

๐Ÿ’ก Lombok Annotation ์ ์šฉ ์—๋Ÿฌ

annotation Processor๋ฅผ ์„ค์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค!

  1. Setting-> Build,Execution,Deployment -> Compiler -> Annotation Processors์„ค์ •์—์„œ Enable Anntation processing ์ฒดํฌ๋ฐ•์Šค ํ™œ์„ฑํ™”
  2. build.gradle ํŒŒ์ผ์—์„œ dependencies**{**annotationProcessor('org.projectlombok:lombok:')} ์ถ”๊ฐ€