Lombok: 보일러플레이트 코드 제거하기 🚀

콘텐츠 대표 이미지 - Lombok: 보일러플레이트 코드 제거하기 🚀

 

 

자바 개발자의 생산성을 높여주는 마법 같은 라이브러리

안녕? 오늘은 자바 개발할 때 정말 유용한 Lombok에 대해 함께 알아볼까? 코드 작성하다 보면 반복되는 지루한 코드들 때문에 손가락 아프고 시간 낭비했던 경험 다들 있지? 그런 고통을 확~ 줄여주는 고마운 친구를 소개할게! 😊

자바 개발자의 고통 보일러플레이트 코드 Lombok으로 해결!

Lombok이 뭐야? 🤔

Lombok은 자바 개발자들의 생산성을 높여주는 라이브러리야. 반복적으로 작성해야 하는 getter, setter, 생성자, equals, hashCode 같은 메서드들을 애노테이션 몇 개로 자동 생성해주는 마법사 같은 존재지! 이런 반복적인 코드를 '보일러플레이트 코드'라고 부르는데, Lombok은 이걸 확~ 줄여줘서 코드가 훨씬 깔끔해지고 가독성도 좋아진다구. 😎

💡 알고 가자! 보일러플레이트(Boilerplate) 코드란?

최소한의 변경으로 여러 곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말해. 마치 찍어내듯이 반복되는 코드라서 이런 이름이 붙었어!

Lombok 시작하기 🚀

Lombok을 사용하려면 먼저 프로젝트에 추가해야 해. Maven이나 Gradle 같은 빌드 도구를 사용한다면 정말 간단하게 추가할 수 있어!

Maven에 추가하기

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

Gradle에 추가하기

compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
        

IDE에서 Lombok을 사용하려면 플러그인도 설치해야 해! IntelliJ나 Eclipse 같은 IDE를 사용한다면 Lombok 플러그인을 설치해주면 IDE가 Lombok이 생성한 코드를 인식할 수 있어. 요즘은 대부분의 최신 IDE 버전에 기본으로 포함되어 있기도 해. 👍

Lombok의 주요 애노테이션들 ✨

이제 Lombok의 진짜 매력, 애노테이션들을 알아볼까? 이 애노테이션들이 바로 코드를 마법처럼 줄여주는 비밀 무기야!

  1. @Getter / @Setter

    클래스의 모든 필드에 대한 getter와 setter 메서드를 자동으로 생성해줘. 필드별로 적용할 수도 있어!

  2. @ToString

    객체의 문자열 표현을 반환하는 toString() 메서드를 자동 생성해줘. 어떤 필드를 포함/제외할지도 설정 가능해!

  3. @EqualsAndHashCode

    equals()와 hashCode() 메서드를 자동으로 생성해줘. 객체 비교와 해시 기반 컬렉션에서 중요하지!

  4. @NoArgsConstructor

    파라미터가 없는 기본 생성자를 생성해줘.

  5. @AllArgsConstructor

    모든 필드를 파라미터로 받는 생성자를 생성해줘.

  6. @RequiredArgsConstructor

    final이나 @NonNull로 표시된 필드만 파라미터로 받는 생성자를 생성해줘.

  7. @Data

    @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 한 번에 적용하는 강력한 애노테이션!

  8. @Builder

    빌더 패턴을 자동으로 구현해주는 애노테이션. 객체 생성을 더 유연하고 가독성 있게 만들어줘.

  9. @Slf4j

    로깅을 위한 Logger 객체를 자동으로 생성해줘. 로그 작성이 훨씬 편해져!

  10. @Value

    불변(immutable) 클래스를 만들어주는 애노테이션. 모든 필드가 private final이 되고, setter가 생성되지 않아.

Lombok 사용 전/후 비교 👀

Lombok의 효과를 직접 눈으로 확인해볼까? 간단한 Person 클래스를 Lombok 사용 전과 후로 비교해볼게!

Lombok 사용 전 😓

public class Person {
    private String name;
    private int age;
    private String email;
    
    // 기본 생성자
    public Person() {
    }
    
    // 모든 필드를 초기화하는 생성자
    public Person(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
    
    // Getter 메서드들
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
    
    public String getEmail() {
        return email;
    }
    
    // Setter 메서드들
    public void setName(String name) {
        this.name = name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
    
    // toString 메서드
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }
    
    // equals 메서드
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name) &&
                Objects.equals(email, person.email);
    }
    
    // hashCode 메서드
    @Override
    public int hashCode() {
        return Objects.hash(name, age, email);
    }
}
        

Lombok 사용 후 😍

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    private String name;
    private int age;
    private String email;
}
        

와우! 50줄 넘는 코드가 단 10줄로 줄었어! 😲

50+ 줄 코드 10줄 코드 Lombok 마법 ✨

Lombok 활용 예제 💻

이제 실제로 Lombok을 활용하는 몇 가지 예제를 살펴볼게! 다양한 상황에서 어떻게 활용할 수 있는지 알아보자.

1. @Builder 패턴 활용하기

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Product {
    private Long id;
    private String name;
    private double price;
    private String category;
    private String description;
}

// 사용 예시
Product phone = Product.builder()
    .id(1L)
    .name("스마트폰")
    .price(1000000)
    .category("전자기기")
    .description("최신형 스마트폰입니다")
    .build();
        

@Builder 애노테이션을 사용하면 객체 생성을 체이닝 방식으로 할 수 있어서 가독성이 훨씬 좋아져! 특히 필드가 많은 클래스에서 유용하지. 👍

2. @Slf4j로 로깅 간편하게 하기

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserService {
    
    public void registerUser(User user) {
        log.info("사용자 등록 시작: {}", user.getEmail());
        
        try {
            // 사용자 등록 로직
            log.debug("사용자 정보 검증 완료");
            // DB 저장 등의 작업
            
            log.info("사용자 등록 완료: {}", user.getId());
        } catch (Exception e) {
            log.error("사용자 등록 실패: {}", e.getMessage(), e);
            throw e;
        }
    }
}
        

@Slf4j 애노테이션 하나로 로거 객체를 자동 생성해주니 매번 Logger 객체를 선언할 필요가 없어! 코드가 훨씬 깔끔해지지. 😊

3. @Value로 불변 객체 만들기

import lombok.Value;

@Value
public class Money {
    String currency;
    double amount;
    
    // 비즈니스 로직 메서드
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("통화가 다릅니다");
        }
        return new Money(this.currency, this.amount + other.amount);
    }
}
        

@Value 애노테이션을 사용하면 모든 필드가 private final이 되고 setter가 생성되지 않아서 불변 객체를 쉽게 만들 수 있어! 스레드 안전성이 보장되어야 하는 경우에 유용하지. 🔒

Lombok 사용 시 주의사항 ⚠️

Lombok이 정말 편리하지만, 몇 가지 주의해야 할 점도 있어! 이런 부분들을 알고 사용하면 더 효과적으로 활용할 수 있을 거야.

  1. 순환 참조 주의

    @ToString이나 @EqualsAndHashCode를 사용할 때 양방향 관계에서 순환 참조가 발생할 수 있어. 이런 경우 exclude 속성을 사용해서 특정 필드를 제외해야 해!

    @ToString(exclude = "parent")
    @EqualsAndHashCode(exclude = "children")
                    
  2. JPA와 함께 사용 시 주의

    JPA 엔티티에 @Data를 무분별하게 사용하면 문제가 생길 수 있어. 특히 @EqualsAndHashCode는 기본적으로 모든 필드를 사용하는데, 이는 JPA에서 권장되지 않아. 대신 @Getter와 필요한 애노테이션만 선택적으로 사용하는 게 좋아!

  3. IDE 설정 필요

    IDE가 Lombok이 생성한 코드를 인식하려면 플러그인 설치가 필요해. 최신 버전의 IDE는 대부분 지원하지만, 팀 프로젝트에서는 모든 팀원이 설정했는지 확인해야 해!

  4. 과도한 사용 자제

    Lombok은 편리하지만, 모든 클래스에 무조건 @Data를 붙이는 건 좋지 않아. 각 애노테이션의 의미를 이해하고 필요한 것만 사용하는 게 좋은 습관이야!

⚠️ Lombok 사용 시 주의사항 1 순환 참조 조심하기 2 JPA와 함께 사용 시 주의 3 필요한 애노테이션만 선택적으로 사용하기

Lombok 실무 활용 팁 💡

실제 프로젝트에서 Lombok을 더 효과적으로 활용할 수 있는 팁들을 알아볼까?

  1. 커스텀 애노테이션 조합하기

    자주 사용하는 애노테이션 조합을 커스텀 애노테이션으로 만들어 사용할 수 있어!

    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.experimental.SuperBuilder;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.SOURCE)
    @Getter
    @NoArgsConstructor
    @SuperBuilder
    public @interface EntityBase {
    }
                    
  2. AccessLevel 활용하기

    @Getter, @Setter 등의 애노테이션에서 접근 레벨을 지정할 수 있어!

    @Getter
    @Setter(AccessLevel.PROTECTED) // protected 접근 레벨의 setter 생성
    public class User {
        private String username;
        private String password;
    }
                    
  3. @Builder.Default 활용하기

    @Builder 패턴에서 기본값을 설정하고 싶을 때 유용해!

    @Builder
    public class Settings {
        @Builder.Default
        private boolean darkMode = false;
        
        @Builder.Default
        private List tags = new ArrayList<>();
    }
                    
  4. @Singular 활용하기

    컬렉션 타입의 필드를 빌더 패턴에서 하나씩 추가할 수 있게 해줘!

    @Builder
    public class ShoppingCart {
        private String customerName;
        
        @Singular
        private List items;
    }
    
    // 사용 예시
    ShoppingCart cart = ShoppingCart.builder()
        .customerName("홍길동")
        .item("사과")
        .item("바나나")
        .item("우유")
        .build();
                    

💡 실무 꿀팁! 재능넷에서 Java 개발 관련 프로젝트를 의뢰하거나 수주할 때, Lombok을 활용하면 코드량을 크게 줄여 생산성을 높일 수 있어! 특히 DTO나 엔티티 클래스가 많은 프로젝트에서 효과가 큰 편이지. 🚀

Lombok의 내부 동작 원리 🔍

Lombok이 어떻게 마법처럼 코드를 생성해주는지 궁금하지 않아? 그 비밀을 살짝 들여다볼게!

Lombok은 자바의 애노테이션 프로세싱(Annotation Processing)을 활용해서 컴파일 시점에 코드를 생성해. 간단히 설명하면 이런 과정으로 동작해:

  1. 소스 코드에 Lombok 애노테이션을 작성해.

  2. 자바 컴파일러가 소스 코드를 컴파일할 때 Lombok의 애노테이션 프로세서가 실행돼.

  3. 애노테이션 프로세서는 추상 구문 트리(AST)를 조작해서 getter, setter 등의 메서드를 추가해.

  4. 최종적으로 컴파일된 클래스 파일에는 이 메서드들이 포함되어 있어!

이런 방식 때문에 IDE에서 Lombok 플러그인이 필요한 거야. IDE가 컴파일 전에도 이런 생성된 메서드들을 인식할 수 있게 해주는 거지! 😉

Lombok 동작 원리 소스 코드 작성 컴파일 시작 바이트코드 생성 Lombok 처리

Lombok 대안과 비교 🔄

Lombok 말고도 보일러플레이트 코드를 줄이는 다른 방법들도 있어. 각각의 장단점을 비교해볼까?

  1. Record (Java 14+)

    Java 14부터 도입된 record는 불변 데이터 클래스를 간결하게 만들 수 있어!

    public record Person(String name, int age, String email) {}
                    

    장점: 표준 Java 기능이라 별도 라이브러리가 필요 없음
    단점: 불변 객체만 가능하고, 상속이 불가능함

  2. AutoValue (Google)

    Google에서 만든 불변 값 클래스 생성 라이브러리야.

    @AutoValue
    public abstract class Person {
        public abstract String name();
        public abstract int age();
        public abstract String email();
        
        public static Person create(String name, int age, String email) {
            return new AutoValue_Person(name, age, email);
        }
    }
                    

    장점: 타입 안전성이 높고 테스트하기 쉬움
    단점: Lombok보다 코드가 더 많이 필요함

  3. Immutables

    불변 객체를 생성하기 위한 또 다른 대안이야.

    @Value.Immutable
    public interface Person {
        String getName();
        int getAge();
        String getEmail();
    }
                    

    장점: 강력한 타입 안전성과 유연한 커스터마이징
    단점: 설정이 복잡하고 학습 곡선이 있음

Lombok은 이런 대안들 중에서도 가장 간결하고 사용하기 쉬운 편이야! 특히 Java 14 이전 버전을 사용하는 프로젝트에서는 Lombok이 최고의 선택이 될 수 있어. 하지만 최신 Java를 사용한다면 record도 좋은 선택이 될 수 있지! 😊

Lombok과 함께 사용하면 좋은 라이브러리들 🛠️

Lombok과 함께 사용하면 시너지 효과를 낼 수 있는 다른 라이브러리들도 알아볼까?