Lombok의 개념과 활용법

CJI0524·2025년 2월 24일
0

Java

목록 보기
4/7

1. 보일러 플레이트 코드 (Boiler Plate Code)와 Lombok

'묻지도 따지지도 않고 따라 적는 코드'를 우리는 보일러 플레이트 (Boiler Plate) 코드라고 한다. 이 용어의 유래는 미국 신문 업계 초창기에 매일 바뀌지 않고 동일한 내용 (신문의 제목, 형태 등 변하지 않는 부분)을 효율적으로 출력하기 위해 작성된 철판 모형을 의미하는 것에서 시작했다.

이런 용어가 프로그래밍으로 넘어와서 '별 수정 없이 반복적으로 사용되는 코드'를 보일러 플레이트라고 한다.

프로그램에서 '별 수정 없이 반복적으로 사용되는 코드'란 쉽게 말해 표준화된 코드들을 의미한다.

예를 들어, 자바 클래스에서 모든 필드에 대해 getter/setter 메서드를 만들어야 하거나, equals(), hashCode(), toString() 같은 메서드를 반복해서 작성하는 부분들이 바로 보일러 플레이트 코드이다.
이런 코드는 실제 비즈니스 로직과는 직접적으로 관련 없고, 단순히 객체의 기본 기능을 구현하기 위해 요구된다.

이런 상황에서 특정 라이브러리를 사용하면 이런 보일러 플레이트 코드들을 어노테이션 한 줄로 대체할 수 있어서, 코드를 더 깔끔하고 간결하게 만들 수 있는데 이것이 바로 Lombok이다.

2. Lombok 라이브러리란?

Lombok (롬복)은 자바에서 보일러 플레이트 코드를 줄여주는 라이브러리이다. 예를 들어, 도메인 클래스나 Entity 같은 클래스는 보통 멤버 변수가 많아서 getter, setter, toString, equals, hashCode, 그리고 여러 생성자 같은 메서드를 반복적으로 작성해야 하는데, 이 과정을 Lombok의 어노테이션 한 줄로 대체할 수 있다.

실제로 Lombok를 이용해 코딩할 때는 어노테이션만 보이고, 컴파일 시점에 자동으로 해당 메서드들이 생성되므로 결과물 (.class 파일)에는 완전한 코드가 포함된다.

Lombok의 유용함을 직접 체감하기 위해 다음과 같은 보일러 플레이트 코드로 가득찬 클래스가 있다고 생각해보자.

✍️ 작성

public class Store extends Common {

    private String companyName;                                 // 상호명
    private String industryTypeCode;                            // 업종코드
    private String businessCodeName;                            // 업태명
    private String industryName;                                // 업종명(종목명)
    private String telephone;                                   // 전화번호
    private String regionMoneyName;                             // 사용가능한 지역화폐 명
    private boolean isBmoneyPossible;                           // 지류형 지역화폐 사용가능 여부
    private boolean isCardPossible;                             // 카드형 지역화폐 사용가능 여부
    private boolean isMobilePossible;                           // 모바일형 지역화폐 사용가능 여부
    private String lotnoAddr;                                   // 소재지 지번주소
    private String roadAddr;                                    // 소재지 도로명주소
    private String zipCode;                                     // 우편번호
    private double longitude;                                   // 경도
    private double latitude;                                    // 위도
    private String sigunCode;                                   // 시군 코드
    private String sigunName;                                   // 시군 이름

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public String getIndustryTypeCode() {
        return industryTypeCode;
    }

    public void setIndustryTypeCode(String industryTypeCode) {
        this.industryTypeCode = industryTypeCode;
    }

    public String getBusinessCodeName() {
        return businessCodeName;
    }

    public void setBusinessCodeName(String businessCodeName) {
        this.businessCodeName = businessCodeName;
    }

    public String getIndustryName() {
        return industryName;
    }

    public void setIndustryName(String industryName) {
        this.industryName = industryName;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getRegionMoneyName() {
        return regionMoneyName;
    }

    public void setRegionMoneyName(String regionMoneyName) {
        this.regionMoneyName = regionMoneyName;
    }

    public boolean isBmoneyPossible() {
        return isBmoneyPossible;
    }

    public void setBmoneyPossible(boolean bmoneyPossible) {
        isBmoneyPossible = bmoneyPossible;
    }

    public boolean isCardPossible() {
        return isCardPossible;
    }

    public void setCardPossible(boolean cardPossible) {
        isCardPossible = cardPossible;
    }

    public boolean isMobilePossible() {
        return isMobilePossible;
    }

    public void setMobilePossible(boolean mobilePossible) {
        isMobilePossible = mobilePossible;
    }

    public String getLotnoAddr() {
        return lotnoAddr;
    }

    public void setLotnoAddr(String lotnoAddr) {
        this.lotnoAddr = lotnoAddr;
    }

    public String getRoadAddr() {
        return roadAddr;
    }

    public void setRoadAddr(String roadAddr) {
        this.roadAddr = roadAddr;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public String getSigunCode() {
        return sigunCode;
    }

    public void setSigunCode(String sigunCode) {
        this.sigunCode = sigunCode;
    }

    public String getSigunName() {
        return sigunName;
    }

    public void setSigunName(String sigunName) {
        this.sigunName = sigunName;
    }

}

이 복잡한 코드를 Lombok 라이브러리를 활용하면 다음과 같이 간단히 줄일 수 있다.

✍️ 작성

@Getter
@Setter
public class Store extends Common {

    private String companyName;                                 // 상호명
    private String industryTypeCode;                            // 업종코드
    private String businessCodeName;                            // 업태명
    private String industryName;                                // 업종명(종목명)
    private String telephone;                                   // 전화번호
    private String regionMoneyName;                             // 사용가능한 지역화폐 명
    private boolean isBmoneyPossible;                           // 지류형 지역화폐 사용가능 여부
    private boolean isCardPossible;                             // 카드형 지역화폐 사용가능 여부
    private boolean isMobilePossible;                           // 모바일형 지역화폐 사용가능 여부
    private String lotnoAddr;                                   // 소재지 지번주소
    private String roadAddr;                                    // 소재지 도로명주소
    private String zipCode;                                     // 우편번호
    private double longitude;                                   // 경도
    private double latitude;                                    // 위도
    private String sigunCode;                                   // 시군 코드
    private String sigunName;                                   // 시군 이름

}

훨씬 간결하고 깔끔해졌다. 이처럼 Lombok을 적절히 사용하면 코드의 가독성을 높이고 생산성을 향샹시킬 수 있다.

3. Lombok의 사용법

Intellij 기준으로 Lombok를 사용할려면 플러그인 메뉴에서 Lombok를 설치하고 build.gradledependencies 부분에 해당 의존성을 추가해준다.

✍️ 작성

implementation 'org.projectlombok:lombok'

이후 Lombok 라이브러리가 제공하는 각종 어노테이션을 사용하여 코드를 작성하면 된다. 이에 해당하는 어노테이션들을 알아보자.

3.1. @Getter / @Setter

필드에 대한 gettersetter 메서드를 자동으로 생성한다.

✍️ 작성

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
    private Long id;
    private String name;
}

이렇게 하면 getId(), setId(Long id), getName(), setName(String name) 메서드가 자동으로 생성된다.

3.2. @ToString

클래스의 toString() 메서드를 자동으로 생성한다.

✍️ 작성

import lombok.ToString;

@ToString
public class User {
    private Long id;
    private String name;
}

자동 생성된 toString()User(id=1, name=John) 처럼 모든 필드를 문자열로 표현한다.

3.3. @EqualsAndHashCode

equals()hashCode() 메서드를 자동으로 생성한다.

✍️ 작성

import lombok.EqualsAndHashCode;

@EqualsAndHashCode
public class User {
    private Long id;
    private String name;
}

이 어노테이션을 사용하면 객체 비교나 컬렉션에서 해시 기반 동작 (예: HashSet, HashMap) 시 유용한 equals()hashCode()가 생성

3.4. @NoArgsConstructor

파라미터 없는 기본 생성자를 생성한다.

✍️ 작성

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class User {
    private Long id;
    private String name;
}

기본 생성자가 필요할 때 이 어노테이션을 붙이면, 아무런 인자 없이 생성할 수 있는 생성자가 자동으로 생성된다.

3.5. @AllArgsConstructor

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

✍️ 작성

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class User {
    private Long id;
    private String name;
}

이 어노테이션 덕분에 모든 필드를 초기화하는 생성자를 별도로 작성할 필요 없이 자동으로 생성한다.

3.6. @RequiredArgsConstructor

final 필드나 @NonNull이 붙은 필드만 인자로 받는 생성자를 생성한다.

✍️ 작성

import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class User {
    @NonNull
    private String name;
    private Long id;
}

해당 예제에서 name 필드에 @NonNull이 붙었으므로, 생성자에는 name만 인자로 들어가고, id는 초기화하지 않아도 된다.

3.7. @Data

@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 한 번에 적용해준다.

✍️ 작성

import lombok.Data;

@Data
public class User {
    private Long id;
    private String name;
}

한 줄의 어노테이션으로 기본적인 메서드들을 모두 자동 생성해주므로, 간결한 코드 작성을 도와준다.

3.8. @Builder

빌더 패턴을 손쉽게 구현할 수 있도록 도와준다.

✍️ 작성

import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class User {
    private Long id;
    private String name;
}

빌더 패턴을 사용하면, 아래처럼 가독성이 좋은 코드로 객체를 생성할 수 있다.

✍️ 작성

User user = User.builder()
                .id(1L)
                .name("John")
                .build();

3.9 @Slf4j (로깅 어노테이션)

SLF4J 기반의 로그 객체를 자동으로 생성한다.

✍️ 작성

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyService {
    public void process() {
        log.info("Processing started.");
    }
}

클래스 내에 private static final org.slf4j.Logger log = ... 같은 로깅 코드를 작성할 필요 없이, 바로 log.info(), log.debug() 등을 사용할 수 있다.

4. 해당 게시글 작성에 참고한 글 목록

보일러 플레이트(Boiler Plate) 이해하기
[Java] Lombok이란? 및 Lombok 활용법
[JAVA] Lombok이란? Lombok 적용하는 방법

profile
개발돌이

0개의 댓글