Spring이나 Spring boot Web 개발을 하다보면, 자주 사용하는 메서드나, 생성자들이 있다.
이는 가독성을 떨어뜨리고, 중복적으로 자주 적다보니 일의 효율이 떨어질 수 있다.
이를 해결해주는 아름다운 라이브러리가 바로 Lombok이다.
Lombok이란?
Lombok은 Java의 주석 기반 라이브러리로, 자주 사용하는 메서드나 생성자 등을 자동으로 생성해 주어 코드의 양을 크게 줄여주는 도구이다. 주로 boilerplate 코드(반복적인 코드)를 제거하는 데 유용하며, 코드의 가독성과 유지 보수성을 높이는 데 도움을 준다.
아래는 Lombok에서 제공하는 어노테이션들이다.
| 어노테이션 | 설명 |
| @Getter | 필드에 대해 Getter 메서드를 자동 생성합니다. |
| @Setter | 필드에 대해 Setter 메서드를 자동 생성합니다. |
| @ToString | toString() 메서드를 자동 생성합니다. |
| @EqualsAndHashCode | equals()와 hashCode() 메서드를 자동 생성합니다. |
| @NoArgsConstructor | 매개변수가 없는 기본 생성자를 자동 생성합니다. |
| @AllArgsConstructor | 모든 필드를 매개변수로 받는 생성자를 자동 생성합니다. |
| @RequiredArgsConstructor | final 또는 @NonNull이 붙은 필드만 매개변수로 받는 생성자를 자동 생성합니다. |
| @Data | @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 모두 포함하는 어노테이션입니다. |
| @Value | @Data와 유사하지만 모든 필드를 final로 만들며 불변 객체를 생성합니다. |
| 어노테이션 | 설명 |
| @Builder | 빌더 패턴을 자동 생성하여 객체 생성 시 필드값을 명시적으로 설정할 수 있게 합니다. |
| @Slf4j | org.slf4j.Logger를 이용한 log 객체를 자동 생성하여 로깅 기능을 제공합니다. |
| @Log4j2 | org.apache.logging.log4j.Logger의 log 객체를 자동 생성합니다. |
| @NonNull | 필드나 매개변수의 값이 null이 되지 않도록 체크합니다. |
| @Synchronized | 동기화된 메서드를 생성하여 멀티스레드 환경에서 안전하게 만듭니다. |
| @With | 불변 객체에서 필드를 변경한 새 객체를 반환합니다. (주로 @Value와 함께 사용) |
| @Cleanup | 리소스를 자동으로 해제하여 try-finally 블록을 대체합니다. |
Lombok 사용 시 장점
그렇다면 이 Lombok이라는 라이브러리를 사용했을 때 우리가 얻을 수 있는 장점이 무엇일까?
- 코드 간결화: 반복적인 코드(예: Getter/Setter, toString 등)를 줄여준다.
- 자동화: 개발자가 일일이 작성해야 하는 메서드를 자동으로 생성해준다.
- 유지보수 용이: 코드를 간결하게 만들어서 유지보수가 용이하다.
- 성능: 런타임에 코드가 동적으로 생성되는 것이 아니라 컴파일 타임에 코드가 생성되므로 성능에 미치는 영향이 거의 없다.
Lombok 사용 시 유의사항
사용하기 전, 몇가지 적용 사항이 있다.
1. 롬복을 사용하려면, 빌드 도구에 Lombok을 의존성으로 추가해야 한다.
Maven
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
Gradle
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.24'
annotationProcessor 'org.projectlombok:lombok:1.18.24'
}
2. 개발 툴에서 플러그인 설치 (Intellij)
File - Settings - Plugins 에서 Lombok 검색

이제 롬복에서 제공하는 어노테이션을 사용할 수 있다!
Lombok 사용법
이 포스팅에서는 자주 쓰이는 어노테이션들만 코드 예시로 다룰 예정이다.
@Getter, @Setter
적용전
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
적용후
@Getter
@Setter
public class Person {
private String name;
private int age;
}
@ToString
적용전
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
적용후
@ToString
public class Person {
private String name;
private int age;
}
@EqualsAndHashCode
적용전
public class Person {
private String name;
private int age;
@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);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
적용후
@EqualsAndHashCode
public class Person {
private String name;
private int age;
}
@NoArgsConstructor, @AllArgsConstructor
적용전
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
적용후
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private int age;
}
@RequiredArgsConstructor 는 final 필드나 @NonNull 필드를 받는 생성자를 생성한다.
Spring에서 생성자 주입을 할 때, Class레벨에 붙여 사용하기도 한다.
@Data
적용전
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@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);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
적용후
@Data
public class Person {
private String name;
private int age;
}
@Builder
적용전
public class Person {
private String name;
private int age;
private Person(PersonBuilder builder) {
this.name = builder.name;
this.age = builder.age;
}
//Nested Builder Class
public static class PersonBuilder {
private String name;
private Integer age;
public PersonBuilder setName(String name) {
this.name = name;
return this;
}
public PersonBuilder setAge(Integer age) {
this.age = age;
return this;
}
public Person build() {
return new Person(this);
}
}
}
적용후
@Builder
public class Person {
private String name;
private int age;
}
@Slf4j
@Slf4j
public class MyClass {
public void logMessage() {
log.info("This is a log message");
}
}
예시 코드에는 필드가 2개뿐이라 드라마틱한 변화는 안보였지만, 만약 필드가 10개 20개 늘어난다면,
Lombok을 사용했을 때와 사용하지 않았을 때의 클래스 코드의 길이는 엄청난 차이가 날 것이다.
이처럼 프로젝트 상황에 맞는 알맞은 라이브러리를 사용하면 개발이나 성능에서도 이점을 가져갈 수 있으니,
적극 활용해도 좋을 것 같다.
'JAVA' 카테고리의 다른 글
| [Java] Mapstruct - Entity와 DTO의 편리한 매핑 (1) | 2024.11.08 |
|---|---|
| [자바/JAVA] 부모 참조(Super, Super Class) (0) | 2024.06.14 |
| [자바/JAVA] 상속(Inheritance) (0) | 2024.06.14 |
| [자바/JAVA] final(상수) (3) | 2024.06.13 |
| [자바/JAVA] Static변수와 Static메서드 (0) | 2024.06.13 |