롬복(Lombok)이란?
어노테이션 기반으로 코드를 자동완성 해주는 라이브러리
Getter
, Setter
, toString
, constructor()
과 같은 코드를 자동완성 시킬 수 있다.- 코드의 가독성을 향상시킨다.
- 코드 자동 생성을 통해 생산성을 향상시킨다.
- 빌더 패턴이나 로그 생성 등 다양한 방면으로도 활용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| public class ArticleForm {
private String title;
private String content;
public ArticleForm(String title, String content) {
this.title = title;
this.content = content;
}
@Override
public String toString() {
return "ArticleForm{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
|
이렇게 생성자, toString()
메서드가 들어간 DTO 코드를
1
2
3
4
5
6
| @AllArgsConstructor
@ToString
public class ArticleForm {
private String title;
private String content;
}
|
이렇게 줄일 수 있다!
롬복 설치하기
- IntelliJ 2020.03 이후 버전에서는 기본 Plugin으로 Lombok이 설치되어 있다.
- 설치되어 있지 않다면, File > Settings > Plugins > Marketplace에 lombok을 검색하고 설치해 준다.
- Spring Boot 프로젝트에서는 다음과 같이
build.gradle
파일 dependencies
에 추가 후 동기화하면 롬복 관련 라이브러리를 인터넷에서 자동으로 다운로드 해준다.
1
2
| compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
|
롬복 사용하기
@Slf4j
println()
문으로 확인하고 싶은 데이터를 검증하면 기록에 남지 않을 뿐더러 서버의 성능에 악영향을 끼친다. 로깅 기능으로 로그를 남겨 서버에서 일어나는 일을 기록해보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| @Slf4j
@Controller
public class ArticleController {
@Autowired
private ArticleRepository articleRepository;
@GetMapping("/articles/new")
public String newArticleForm() {
return "articles/new";
}
@PostMapping("/articles/create")
public String createArticle(ArticleForm form) {
Article article = form.toEntity();
log.info(article.toString());
Article saved = articleRepository.save(article);
log.info(form.toString());
return "";
}
}
|
롬복의 @Slf4j
어노테이션을 사용하면 log.info()
를 통해 원하는 내용을 로그에 남길 수 있다.
@ToString
- Lombok이 ToString 메서드를 생성해준다.
includeFieldNames
옵션으로 필드명을 포함할지 설정할 수 있다. - 추가 옵션을 설정하지 않으면
MyClass(foo=123, bar=234)
형태로 출력된다. - 출력을 원하지 않는 변수에는
@ToString.Exclude
어노테이션을 붙여준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| public class LombokTestForm {
private String name;
private Integer age;
private String gender;
private String phoneNumber;
@Override
public String toString() {
return "LombokTestForm{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
'}';
}
}
|
1
2
3
4
5
6
7
| @ToString
public class LombokTestForm {
private String name;
private Integer age;
private String gender;
private String phoneNumber;
}
|
@Getter/@Setter
- Getter, Setter 메서드를 만들어 준다.
1
2
3
4
5
6
7
8
9
| @Getter
@Setter
@ToString
public class LombokTestForm {
private String name;
private Integer age;
private String gender;
private String phoneNumber;
}
|
@NonNull
With Lombok
1
2
3
4
5
6
7
8
| public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
}
|
Vanilla Java
1
2
3
4
5
6
7
8
9
10
11
12
13
| public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
// Null 검사문을 생성한다.
// 만약 person이 존재하지 않으면 NullPointerException을 던진다.
if (person == null) {
throw new NullPointerException("person is marked non-null but is null");
}
this.name = person.getName();
}
}
|
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
@NoArgsConstructor
: 매개변수가 없는 생성자를 생성한다.@RequiredArgsConstructor
: 특별한 처리가 필요한 각 필드에 대해 1개의 매개변수가 있는 생성자를 생성한다. 초기화되지 않은 모든 최종 필드는 매개변수를 가지며 선언된 위치에서 초기화되지 않은 @NonNull로 표시된 모든 필드도 가져온다. @NonNull로 표시된 필드의 경우 명시적 Null 검사도 생성된다.@AllArgsConstructor
: 클래스의 각 필드에 대해 1개의 매개변수가 있는 생성자를 생성한다. @NonNull로 표시된 필드는 해당 매개변수에 대해 null 검사를 수행한다.
With Lombok
1
2
3
4
5
6
7
8
9
10
11
| @RequiredArgsConstructor(staticName = "of")
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
@NoArgsConstructor
public static class NoArgsExample {
@NonNull private String field;
}
}
|
Vanilla Java
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
| public class ConstructorExample<T> {
private int x, y;
@NonNull private T description;
// @RequiredArgsConstructor에 의해 만들어지는 메서드
// 특정 변수만을 활용한 생성자를 만들어준다.
private ConstructorExample(T description) {
if (description == null) throw new NullPointerException("description");
this.description = description;
}
public static <T> ConstructorExample<T> of(T description) {
return new ConstructorExample<T>(description);
}
// @AllArgsConstructor에 의해 만들어지는 메서드
// AccessLevel을 Protected로 설정했으므로 protected로 만들어진다.
// 모든 매개변수가 있는 생성자를 생성하고 description에 대해 Null 검사를 수행한다.
@java.beans.ConstructorProperties({"x", "y", "description"})
protected ConstructorExample(int x, int y, T description) {
if (description == null) throw new NullPointerException("description");
this.x = x;
this.y = y;
this.description = description;
}
// @NoArgsConstructor에 의해 만들어지는 메서드
// 매개변수가 없는 생성자를 생성한다.
public static class NoArgsExample {
@NonNull private String field;
public NoArgsExample() {
}
}
}
|
@Data
@ToString
, @EqualsAndHashCode
, @Getter/Setter
, @RequiredArgsConstructor
를 자동완성 시켜준다.- 실무에서는 무겁고 객체의 안정성을 지키기 위해 잘 사용되지 않는다고 한다.
@EqualsAndHashCode
- 클래스에 대한
equals
함수와 hashCode
함수를 자동으로 생성해준다. - 예를 들어,
name
, gender
, phoneNumber
가 같은 객체는 같은 객체로 판단하고 싶다면 아래와 같이 작성하면 된다.
With Lombok
1
2
3
4
5
6
7
8
9
| @EqualsAndHashCode(of = {"name", "gender", "phoneNumber"})
public class LombokTestForm {
private Long id;
private String name;
private Integer age;
private String gender;
private String phoneNumber;
private String address;
}
|
Vanilla Java
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
| public class People {
private Long id;
private String name;
private Integer age;
private boolean gender;
private String phoneNumber;
private String address;
public People(String name, Integer age, String phoneNumber) {
this.name = name;
this.age = age;
this.phoneNumber = phoneNumber;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof People people)) return false;
return gender == people.gender && Objects.equals(name, people.name) && Objects.equals(phoneNumber, people.phoneNumber);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age, gender, phoneNumber, address);
}
}
|
🔗 참고자료
📚 더 공부해야 할 것
- Log 관련 어노테이션이 많은데(Log, Log4j, Log4j2, Slf4j, XSlf4j, JBossLog…) 각각의 차이점이 뭘까? 어떤 어노테이션을 사용하는게 좋을까?