Java

[Spring Boot] Lombok

yerinpark 2023. 10. 24. 20:53

Intro

Spring Boot를 사용하면서 Lombok을 너무나 당연하게 써왔다.

JPA의 필수 도구인 Lombok에 대한 강의를 들으면서 Annotation의 의미, 활용법과 어떤 원리로 쓰이는지 잘 이해할 수 있었다.

 

Lombok

JPA의 필수 도구. 여러 개의 field 변수를 가지고 캡슐화 원칙에 의해 Getter, Setter를 많이 만들어야 하는 JPA의 특성상, 꼭 필요한 라이브러리이다.

 

c.f. JPA와는 별개의 라이브러리이다.

 

 

 

 

JPA에서의 Entity 기본 구조

field 변수와 Getter, Setter의 조합으로 만들어진다. 

 

 

 

 

 

Lombok Annotation이 원래는 어떤 형태일까?

domain package를 만들고 하위에 User 클래스를 만들었다.

Lombok, Delombok은 우클릭 > Refactor에서도 할 수 있다. 

 

 

 

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
public class User {
    private String name;
    private String email;
    /* 생성된 시간과 수정된 시간은 일반적으로 JPA domain 객체에 항상 포함하도록 한다. */
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
}

이 코드를 Lombok을 Refactor를 통해 Delombok 해보면

 

package com.example.bookmanager.domain;

import java.time.LocalDateTime;

public class User {
    private String name;
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

    public String getName() {
        return this.name;
    }

    public String getEmail() {
        return this.email;
    }

    public LocalDateTime getCreatedAt() {
        return this.createdAt;
    }

    public LocalDateTime getUpdatedAt() {
        return this.updatedAt;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }

    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }

    public String toString() {
        return "User(name=" + this.getName() + ", email=" + this.getEmail() + ", createdAt=" + this.getCreatedAt() + ", updatedAt=" + this.getUpdatedAt() + ")";
    }
}

원래의 코드로 바꿔준다.

 

 

 

 

@ToString을 사용하는 이유

우선, entity 클래스에서 Ctrl + Shift + T 단축키를 써서 JUnit5 테스트를 만든다.

import org.junit.jupiter.api.Test;

class UserTest {
    @Test
    void test() {
        User user = new User();
        user.setEmail("haejunkim@metacomedy.net");
        System.out.println(user);
    }
}

위의 코드를 테스트를 해보면

 

com.example.bookmanager.domain.User@456d6c1e

위와 같은 결과가 나와 오류가 발생하거나 디버깅할 때 불편함을 초래한다.

 

여기서 toString은 @Override해서 사용할 수 있다.

(Java의 모든 클래스는 Object를 상속받고 있으므로, toString을 재정의할 수 있다.)

 

 

    public String toString() {
        return "User(name=" + this.getName() + ", email=" + this.getEmail() + ", createdAt=" + this.getCreatedAt() + ", updatedAt=" + this.getUpdatedAt() + ")";
    }

Lombok에서는 일일이 toString을 재정의하지 않고도 Annotation만으로도 사용할 수 있다.

 

 

 

 

생성자 관련 Lombok Annotation

오픈 소스 추세가 가독성이 좋은 코드이다.

 

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

class UserTest {
    @Test
    void test() {
        User user = new User();
        user.setName("minho");
        user.setEmail("haejunkim@metacomedy.net");
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        User user1 = new User("minho", "haejunkim@metacomedy.net", LocalDateTime.now(), LocalDateTime.now());

        System.out.println(user);
    }
}

 

@NoArgsConstructor

아무런 인자를 주지 않고 생성하는 생성자가 NoArgsConstructor이다.

JPA에서는 인자 없이 생성하는 생성자가 반드시 필요하므로 @NoArgsConstructor를 항상 선언해주어야 한다.

위의 코드에서 user에 해당한다.(setter를 사용해 data를 넣음)

 

@AllArgsConstructor

객체가 가지고 있는 모든 field를 인자로 받아서 생성해주는 것.

위의 코드에서 user1에 해당한다.(한번에 data를 넣음)

 

@RequiredArgsConstructor

꼭 필요한 인자만을 이용해서 생성자를 만들어 준다.

 

package com.example.bookmanager.domain;

import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class User {
    private String name;
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

}

이 코드에서 @NoArgsConstructor@RequiredArgsConstructor는 같은 동작을 하게 된다.

 

 

 

import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor
public class User {
    @NonNull
    private String name;
    @NonNull
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

}

 

package com.example.bookmanager.domain;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

class UserTest {
    @Test
    void test() {
        User user = new User();
        user.setName("minho");
        user.setEmail("haejunkim@metacomedy.com");
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        User user1 = new User("minho", "haejunkim@metacomedy.net", LocalDateTime.now(), LocalDateTime.now());
        User user2 = new User("minho", "haejunkim@metacomedy.net");

        System.out.println(user);
    }
}

Lombok에서 제공하는 @NonNull Annotation을 붙인 field만으로 생성할 수 있다.

 

 

package com.example.bookmanager.domain;

import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.ToString;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
public class User {
    @NonNull
    private String name;
    @NonNull
    private String email;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

    public User(@NonNull String name, @NonNull String email, LocalDateTime createdAt, LocalDateTime updatedAt) {
        this.name = name;
        this.email = email;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }

    public User() {
    }

    public User(@NonNull String name, @NonNull String email) {
        this.name = name;
        this.email = email;
    }
}

마찬가지로 Delombok을 해보면 위와 같이 확인해볼 수 있다.