개발 생산성을 10배 높여주는 Lombok 어노테이션 총정리

DU·2025년 8월 23일
0

이번 포스팅에서는 Lombok 라이브러리가 제공하는 어노테이션들을 예제 코드와 함께 자세히 알아보겠습니다.


1. 생성자 어노테이션: 객체 생성 방식을 자유롭게

객체를 생성하는 방법은 여러 가지가 있으며, Lombok은 각 상황에 맞는 생성자를 자동으로 만들어줍니다.

@NoArgsConstructor (기본 생성자)

인자가 없는 기본 생성자를 만듭니다.

  • 사용 목적:

    • JPA(Java Persistence API): JPA는 데이터베이스에서 엔티티를 조회할 때 리플렉션(Reflection)을 통해 객체를 생성하는데, 이때 기본 생성자가 반드시 필요합니다.
    • JSON 직렬화/역직렬화: Jackson이나 Gson 같은 라이브러리가 JSON 데이터를 객체로 변환할 때도 기본 생성자를 사용합니다.
  • 예제:

@NoArgsConstructor
public class Book {
    private String title;
    private String author;
}

// Lombok이 생성하는 코드:
// public Book() {}

@AllArgsConstructor (모든 필드 생성자)

클래스의 모든 필드를 인자로 받는 생성자를 만듭니다.

  • 사용 목적:
    • 객체를 생성하는 시점에 모든 필드를 한 번에 초기화할 때 유용합니다.
  • 예제:
@AllArgsConstructor
public class Book {
    private String title;
    private String author;
}

// Lombok이 생성하는 코드:
// public Book(String title, String author) {
//     this.title = title;
//     this.author = author;
// }

@RequiredArgsConstructor (필수 필드 생성자)

final로 선언되었거나 @NonNull 어노테이션이 붙은 필수 필드만을 인자로 받는 생성자를 만듭니다.

  • 사용 목적:

    • 의존성 주입(Dependency Injection): 스프링(Spring) 프레임워크에서 가장 흔히 사용되는 방식으로, 반드시 필요한 의존성만 모아 생성자를 만들 수 있어 안정적입니다.
    • 불변 객체: final 필드를 사용해 불변 객체를 생성할 때 매우 유용합니다.
  • 예제:

@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    
    @NonNull
    private String version;
}

// Lombok이 생성하는 코드:
// public UserService(UserRepository userRepository, String version) {
//     this.userRepository = userRepository;
//     this.version = version;
// }

@Builder (빌더 패턴)

가장 강력하고 유연한 생성 방식으로, 빌더 패턴을 자동으로 구현해 줍니다.

  • 사용 목적:

    • 필드가 많은 경우: 필드가 5개 이상일 때 @AllArgsConstructor보다 훨씬 명확하고 안전합니다.
    • 선택적 필드: 모든 필드가 필수적이지 않고, 일부 필드만 설정하고 싶을 때 사용하면 코드가 깔끔해집니다.
  • 예제:

@Builder
public class UserProfile {
    private String name;
    private int age;
    private String email;
    private boolean isPublic;
}

// 사용 방법:
UserProfile profile = UserProfile.builder()
                        .name("Alice")
                        .age(30)
                        .isPublic(true) // 이메일은 선택적으로 생략 가능
                        .build();

2. 보일러플레이트(Boilerplate) 코드 제거

매일 반복해서 작성하는 Getter, Setter, toString() 같은 메서드들도 Lombok을 사용하면 한 줄로 해결할 수 있습니다.

@Getter & @Setter

필드에 대한 Getter와 Setter 메서드를 자동으로 생성해줍니다.

  • 사용 목적:

    • @Getter: 객체의 데이터를 읽어와야 할 때 주로 사용합니다.
    • @Setter: 외부에서 필드의 값을 변경해야 할 때 사용합니다. 불변 객체를 만들 때는 @Setter를 사용하지 않는 것이 좋습니다.
  • 예제:

public class Product {
    @Getter @Setter private String name;
    @Getter private int price; // price는 변경 불가능하게 설정
}

// Lombok이 생성하는 코드:
// public String getName() { return name; }
// public void setName(String name) { this.name = name; }
// public int getPrice() { return price; }

@ToString

객체의 필드 값들을 포함하는 toString() 메서드를 자동으로 만들어줍니다.

  • 사용 목적:

    • 디버깅: 객체의 현재 상태를 로그로 출력하거나 디버깅 툴에서 확인할 때 매우 편리합니다.
    • 예외 처리: 예외 로그에 객체 상태를 포함시켜 문제를 빠르게 파악할 수 있습니다.
  • 예제:

@ToString(exclude = "password") // password 필드는 제외
public class User {
    private String username;
    private String password;
    private String email;
}

// User 객체 출력 시:
// User(username=johndoe, email=john@example.com)

@EqualsAndHashCode

equals()hashCode() 메서드를 자동으로 오버라이딩합니다.

  • 사용 목적:
    • 객체 비교: 두 객체가 논리적으로 동일한지 비교해야 할 때 사용합니다.
    • 컬렉션 사용: HashSet이나 HashMap 같은 컬렉션에 객체를 저장할 때, hashCode()를 이용해 성능을 높일 수 있습니다.
  • 예제:
@EqualsAndHashCode
public class Point {
    private int x;
    private int y;
}

// 두 Point 객체 비교
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
p1.equals(p2); // true

@Data (최강의 종합 어노테이션)

@Data@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor모두 포함하는 종합 선물 세트입니다.

  • 사용 목적:

    • DTO(Data Transfer Object): 데이터를 담아 계층 간에 전달하는 역할을 하는 DTO 클래스에 주로 사용됩니다.
  • 주의점: 엔티티 클래스에서는 데이터베이스 테이블의 컬럼을 직접 변경하는 @Setter를 함부로 사용하는 것을 지양해야 합니다.

  • 예제:

@Data
public class PostDto {
    private String title;
    private String content;
}

마치며

이러한 Lombok 어노테이션들은 개발자가 비즈니스 로직에 더 집중할 수 있게 도와줍니다. 코드를 간결하게 만들고 유지보수를 쉽게 하는 어노테이션을 잘 활용하여 생산성을 높여 보세요!

0개의 댓글