본문 바로가기

Programming Language/Java & Scala

Java의 축복 Lombok 소개 - gradle 적용시키기


Lombok Project는 Java프로젝트를 할때 필수적으로 깔고 시작해야할 툴 중 하나이다. Lombok없이는 Java프로젝트는 수많은 삽질과 노가다로 떡칠 되어있을 것이다. 왜 Lombok을 사용해야 하는지 아래 코드 예제들을 통해 알아보자.



1. 반복적인 코드제거

Java는 훌륭한 언어이지만 코드를 반복적으로 써야하는 경우가 많다. Lombok은 이러한 반복적인 작업을 줄여준다. 만약 프로젝트가 Maven으로 이루어질 경우 아래와 같이 설정한다. (가장 최신 버젼의 추가방법은 이 웹페이지에서 확인가능하다)


pom.xml

1
2
3
4
5
6
7
8
<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.16</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
cs


build.gradle(2.12이상의 gradle)

1
compileOnly "org.projectlombok:lombok:1.16.16"
cs



2. Java의 Getter, Setter, 생성자의 자동생성 

Java의 encapsulation(Java Object설명 at Oracle Doc)은 Java를 활용하는데 기본이다. 그런데 encapsulation을 수행하는데 있어 게터, 세터, 생성자들은 필수적이다. 이러한 귀찮은 게터, 세터, 생성자는 최신 IDE에서는 자동으로 생성해줘서 개발자가 크게 신경쓸 필요가 없어보인다. 그러나 코드에 남겨지게되고 결국 새로운 Object의 field들이 추가될때마다 게터, 세터 들을 또 생성해줘야하는 단점이 있다. 이를 Lombok이 해결해준다.


Without Lombok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class GetterSetterExample {
  /**
   * Age of the person. Water is wet.
   */
  private int age = 10;
 
  /**
   * Name of the person.
   */
  private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
  
  /**
   * Age of the person. Water is wet.
   *
   * @return The current value of this person's age. Circles are round.
   */
  public int getAge() {
    return age;
  }
  
  /**
   * Age of the person. Water is wet.
   *
   * @param age New value for this person's age. Sky is blue.
   */
  public void setAge(int age) {
    this.age = age;
  }
  
  /**
   * Changes the name of this person.
   *
   * @param name The new value.
   */
  protected void setName(String name) {
    this.name = name;
  }
}
cs


With Lombok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
 
public class GetterSetterExample {
  /**
   * Age of the person. Water is wet.
   * 
   * @param age New value for this person's age. Sky is blue.
   * @return The current value of this person's age. Circles are round.
   */
  @Getter @Setter private int age = 10;
  
  /**
   * Name of the person.
   * -- SETTER --
   * Changes the name of this person.
   * 
   * @param name The new value.
   */
  @Setter(AccessLevel.PROTECTED) private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
}
cs


위 코드면 부연 설명이 없어도 어떻게 getter, setter 그리고 추가적으로 AccessLevel이 동작하는지 바로 알 수 있다.

AccessLevel은 Lombok의 configure key로서 여러추가적인 설정이 가능하다. 


만약 Object의 모든 field들에 대해서 getter, setter들을 설정하자면 아래코드와 같이 설정도 가능하다.

With Lombok(all field needs getter, setter and lead to an empty constructor generation)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
 
@Getter @Setter @NoArgsConstructor // NoArgsConstructor은 empty constructor을 자동생성
public class GetterSetterExample {
 
  private int age = 10;
  private String name;
  
  @Override public String toString() {
    return String.format("%s (age: %d)", name, age);
  }
}
 
cs



3. Value Classes/DTO's

Java의 data type을 설정하고 수행할때, 복잡한 "Values" 혹은 "Data Transfer Object"라고 불리는 Object를 생성하여 사용한다. 아래와 같이 POJO(Plain Old Java Object) type의 login을 위한 DTO모델을 만들 수 있다.


Without Lombok

1
2
3
4
5
6
7
8
9
10
public class LoginsResult {
 
    private final Instant loginsTs;
    private final String authsToken;
    private final Duration tokensValidity;
    private final URL tokensRefreshUrl;
 
    //생성자 및 field의 nullcheck 코드들
    //read-only field getter 코드들
}
cs


위 코드는 완전하지 않다. 위 코드에 더하여 생성자는 각 field들에 대하여 null check를 하는 코드를 넣어야하며, readonly만 될 수 있도록 getter을 넣어야 한다.

하지만 이러한 귀찮고 긴 작업들은 Lombok의 준비된 annotation으로 활용가능하다.


With Lombok

1
2
3
4
5
6
7
8
9
@RequiredArgsConstructor
@Accessors(fluent = true) @Getter
public class LoginsResult {
 
    private final @NonNull Instant loginsTs;
    private final @NonNull String authsToken;
    private final @NonNull Duration tokensValidity;
    private final @NonNull URL tokensRefreshUrl;
}
cs


4.자동 Builder Pattern

Java에서는 유연한 Object를 만들기 위해 필요한 field만 정의하여 수행하는 builder pattern(Builder pattern이란?)을 사용하기도 한다. 하지만 builder pattern은 그 자체로서 패턴을 만드는데 코드가 많이 필요하며 개발자가 고려해야할 것들이 너무 많다. 하지만 Lombok과 함께라면?


Without Lombok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class Person {
    private final string name;
    private final string blood;
    private final int age;
    private final int hairColor;
    public static class Builder {
        private final string name;
        private final string blood;
        private int age;
        private int hairColor;
        public Builder(string name, string blood) {
            //객체 생성에 반드시 받아야 하는 파라미터는 Builder에서 받음.
            this.name = name;
            this.blood = blood;
        }
        public Builder age(int age) {
            this.age = age;
            return this;
        }
        public Builder hairColor(int hairColor) {
            this.hairColor = hairColor;
            return this;
        }
        public Rects build() {
            return new Person(this);
            //마지막 build에서 완성.
        }
    }
    public static void main(String args[]) {
        
        //with builder pattern
        Person somin = new Person("somin","A");
        Person wonYoung = new Person("won young","B").age(14);
        Person hyunJun = new Person("hyun jun","c").age(12).hairColor(124);
    }
}
cs


With Lombok

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Builder
public class Person {
    private final string name;
    private final string blood;
    private final int age;
    private final int hairColor;
 
    public static void main(String args[]) {
        
        //with builder pattern
        Person somin = new Person("somin","A");
        Person wonYoung = new Person("won young","B").age(14);
        Person hyunJun = new Person("hyun jun","c").age(12).hairColor(124);
    }
}
cs




5. 그 외에도 유용한 기능들

그 외에도 유용한 기능들을 쓸 수 있다. 각 기능들에 대해서는 url링크를 걸어 놓았다.



6. Lombok 복구하기 - Lombok Doc(@Delombok)

Java project를 하면서 Lombok을 자유롭고 편하고 유용하게 쓸수 있지만 그러나 피치못할 사정으로 Lombok을 원복해야 할 때도 있다. 그럴때는 Lombok에서 제공하는 delombok tool을 사용하면 간단하게 project의 lombok코드들을 다시 자바코드로 복원 가능하다.


In command-line for whole project src files
1
java -jar lombok.jar delombok src -d src-delomboked
cs


In command-line for single java file

1
java -jar lombok.jar delombok -p MyJavaFile.java
cs



7. 결론

이 포스트에서 모든 Lombok 기능들을 수록하지는 못하였지만 이 url에서 모든 기능들을 자세히 살펴볼 수 있다. 또한 각 기능들은 built-in된 configuration system(옵션) 이 있으므로 각자 필요에 따라 적용하여 사용이 가능하다. Lombok을 지금 당장 사용해서 2배 3배 100배가 된 생산성으로 더 나은 프로젝트를 만들어 보는건 어떨까?


End of Document