본문 바로가기
Web/Spring Boot

Spring Boot - Lombok 현명하게 잘 사용하는 방법

by 주남2 2023. 8. 31.
반응형

 

예전 자바에서 클래스를 만들 때 getter, setter, toString 등을 직접 만들며 귀찮은 시간을 보냈던 경험이 다들 있으시지 않나요?

요즘은 IDE 에서 간단한 설정을 통해 getter, setter 를 자동으로 만들어준다고 하지만 이 조차 클래스 내에서 코드 길이가 길어지고 귀찮음을 느낄 때가 많았습니다.

 

이제는 다들 Lombok 을 많이 사용하실 탠데요. 이를 어떻게 하면 안전하고 현명하게 사용할 수 있을지에 대해 알아보겠습니다.

 

Lombok 이란?

1. 애노테이션 기반 코드 생성

Lombok은 어노테이션을 사용하여 컴파일 시점에 코드를 자동으로 생성합니다.

예를 들어, @Getter 및 @Setter 애노테이션은 필드에 대한 게터와 세터 메서드를 자동으로 생성해줍니다.

 

2. 불필요한 코드 제거

Lombok은 @Data 애노테이션을 통해 클래스 내부에서 일반적으로 작성해야 하는 toString(), equals(), hashCode() 등의 메서드를 자동으로 생성합니다. 이렇게 함으로써 개발자는 이러한 반복적인 작업을 수동으로 구현할 필요가 없어집니다.

 

3. 불변 객체 생성

@Value 애노테이션을 사용하면 불변(immutable) 객체를 쉽게 생성할 수 있습니다. Lombok은 final 필드, 생성자, equals() 및 hashCode() 메서드 등을 자동으로 추가하여 불변성을 보장합니다.

 

 

코드로 예시를 들면,

import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100, unique = true)
    private String username;

    @Column(nullable = false, length = 100)
    private String password;
    
    @CreationTimestamp
    private Timestamp createDate;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Timestamp getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Timestamp createDate) {
        this.createDate = createDate;
    }
}

 

import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;

import java.sql.Timestamp;

@Entity
@Data
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100, unique = true)
    private String username;

    @Column(nullable = false, length = 100)
    private String password;

    @CreationTimestamp
    private Timestamp createDate;
}

@Data 어노테이션 하나로 간단하게 정리가 됩니다.

하지만 이를 남용하게 되면 여러 보안적인 문제가 생길 수 있는데요. 하나씩 알아보면서 안전하게 사용하는 방법에 대해 알아보겠습니다.

 

@Data 의 남용은 좋지 않습니다.

실제로 인텔리제이에서 @Data 어노테이션을 사용하면 다음과 같은 경고가 나타납니다.

@Data 는 모든 필드에 대해서 setter 함수까지 만들어주게 되는데, 이렇게 되면 원하지 않는 값이 변경되는 문제가 발생할 수 있습니다.

위의 코드로 예를 들면, createDate 필드는 생성될 때 딱 한번만 사용되고 그 후로는 값이 바뀌면 안됩니다.

 

하지만 @Data 를 사용하여 setter 함수가 만들어지게 되면 언제든 바뀔 수 있는 가능성이 생기게 됩니다. 

따라서 @Data -> @Getter 함수를 사용하여 최대한 안정성 있게 객체를 만드는 것이 좋습니다.

import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;

import java.sql.Timestamp;

@Entity
@Getter
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100, unique = true)
    private String username;

    @Column(nullable = false, length = 100)
    private String password;

    @CreationTimestamp
    private Timestamp createDate;
}

여기에 어떤 것들이 더 추가되면 좋을까요?

 

열심히 찾아보고 공부를 해본 결과, 

@Getter / @NoArgsConstructor / @Builder 를 사용한 조합을 추천드립니다.

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100, unique = true)
    private String username;

    @Column(nullable = false, length = 100)
    private String password;

    @CreationTimestamp
    @Column(nullable = false, updatable = false)
    private Timestamp createDate;

    @Builder
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}

다음과 같이 사용하여 접근할 일이 없는 필드에 대해서는 @NoArgsConstructor 를 통해setter 를 할 수 없도록 막고,

꼭 접근이 필요한 필드에 대해서만 @Builder 를 통해 안전한 객체를 만들 수 있도록 하는 것이 좋겠습니다.

반응형