LostCatBox

AboutLombokAtSpring

Word count: 642Reading time: 4 min
2022/12/24 Share

Lombok 에너테이션 각 장단점

왜?

@Data를 간편하게 활용하는 것이 결국 보안적인 이슈를 생성하는 것을 알았다. 이유를 정리해보고 각각의 lombok에서 주로 쓰는 것들을 정리해보았다.

일단 @Data는 다음의 모든것이 한번에 정의되어있는것과 같다

  • Getter, Setter, RequiredArgsConstructor, ToString, EqualsAndHashCode, Value

따라서 각자의 장단점을 알면 결국 @Data의 단점을 알수있을것이다.

spring4.3부터는 생성자가 존재시 기본적으로 @Autowired가 되며, setter로 주입하고싶다면, @Autowired(required=false)를 통해 기능을 해제해줘야한다.

AllArgsConstructor

클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성한다.

발생할수있는 문제

이 애너테이션은 필드의 선언 순서대로 생성자 파라미터의 순서를 정한다. 따라서 개발자가 혹여나 필드의 선언 순서를 바꾸고 (혹시 타입까지 같다면) 에러가 없이 잘못동작할수있다.

1
2
3
4
5
6
7
@AllArgsConstructor // @RequiredArgsConstructor도 마찬가지
public static class Order{
private long cancelPrice;
private long orderPrice;
}
//취소 금액 5000원, 주문금액 10000원
Order order = new Order(5000L, 10000L)

만약 필드 선언 순서가 cancelPrice와 orderPrice의 위치가 바뀐다면,,, 대참사다

RequiredArgsConstructor

초기화 되지 않는 모든 final 필드 + @NonNull과 같이 제약조건이 설정되어있는 모든 필드들에 대한 생성자를 자동으로 생성한다.

발생할수있는 문제

위 @AllArgsConstructor와 동일한 문제 발생가능

EqualsAndHashCode

equals 메서드와 hashcode 메서드를 생성한다.

set에서 contains를 활용시 equals()를 사용하여, true를 찾는다.

발생할수있는 문제

동일한 객체임이도 Set 에 저장한 뒤에 필드 값을 변경하면 hashCode가 변경되면서 찾을 수 없게 되어버린다. 이는 @EqualsAndHashCode의 문제라기 보다는 변경가능한 필드에 이를 남발함으로써 생기는 문제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@EqualsAndHashCode
public static class Order {
private Long orderId;
private long orderPrice;
private long cancelPrice;

public Order(Long orderId, long orderPrice, long cancelPrice) {
this.orderId = orderId;
this.orderPrice = orderPrice;
this.cancelPrice = cancelPrice;
}
}

Order order = new Order(1000L, 19800L, 0L);

Set<Order> orders = new HashSet<>();
orders.add(order); // Set에 객체 추가

System.out.println("변경전 : " + orders.contains(order)); // true

order.setCancelPrice(5000L); // cancelPrice 값 변경
System.out.println("변경후 : " + orders.contains(order)); // false@EqualsAndHashCode

참고로 hashCode()와 equals() 관계

  • 두 객체가 같으면(equals()가 true 리턴), hashCode()는 같은 값을 리턴해야 합니다.
  • 두 객체가 같지 않을 때 (hashCode()가 false), hashCode()가 꼭 다른 값을 리턴해야하는 것은 아닙니다. 하지만 다른 값을 리턴하면 hash table의 성능이 향상됩니다.
  • hashcode가 다르면, 두개의 객체가 같지 않다
  • hashcode가 같으면, 두개의 객체가 같거나 다를 수 있다→ hashcode가같다면 equals()로 다시검토하게됨. 하지만 hashcode 중복이 없을수록 성능좋아짐

NoArgsConstructor

파라미터가 없는 생성자를 생성한다.

그냥 빈 생성자 만들어줌

발생할수있는 문제

  • 필드들이 final로 생성되어 있는 경우에는 필드를 초기화할수없기 때문에 생성자를 만들수없고 에러가 발생한다. → force=ture 옵션을 이용해 강제 초기화 시켜 생성자를 만들수있다
  • @Nonnull 같은 필드에 제약조건이 설정되어있는경우, 추후 초기화를 진행하기전까지 생성자 내 null-check 로직이 생성되지않는다.

@Data 위험성

발생할수있는 문제

@Data는 다음과 같이 많은 것들이 함께 정의되는것이다

  • Getter, Setter, RequiredArgsConstructor, ToString, EqualsAndHashCode, Value

스크린샷 2022-08-13 오전 1.57.26.png

@Getter @Setter 주의해야한다. 이유는?

  • @Setter는 꼭 필요한 경우에만 설정해야 한다고 알고 있다. 값을 바꿀 수 있는 어노테이션이기 때문에, 값을 바꿀 필요가 있는 경우에만 설정하고 이외의 상황에는 절대 선언하면 안된다.
  • @Getter도 필요한 경우에만 설정하는 것이 가장 좋지만, 남발해도 크게 위험하지 않는 것(?)으로 알고 있다. 값에 접근은 가능하나 변경할 수 없기 때문이다.

그 밖에 롬복 주로 사용하는것

@Getter

모든 각 필드에 해당하는 getXXX메서드 만들어줌

명시적으로 AccessLevel을 명시해주지 않으면, 접근 제한자는 public이 됩니다.

@Setter

모든 각 필드에 해당하는 setXXX메서드 만들어줌

주의할 사항은 Setter는 외부에서 필드를 수정할수있도록 하므로 경우에 따라서 보안에 취약

명시적으로 AccessLevel을 명시해주지 않으면, 접근 제한자는 public이 됩니다.

@ToString

  • toString() 메서드를 작성해줌, exclude 속성사용시, 특정 필드를 toString()결과에서 제외시킬수있다.
1
2
3
4
5
6
7
@ToString(exclude = "password")
public class User {
private Long id;
private String username;
private String password;
private int[] scores;
}

@Builder

  • @Builder를 사용하면 객체 생성이 명확해진다. 가급적 클래스 보다는 직접 만든 생성자 혹은 static 객체 생성 메소드에 붙이는 것을 권장한다.
  • @Builder를 붙이면 파라미터 순서가 아닌 이름으로 값을 설정하기 때문에 리팩토링에 유연하게 대응할 수 있고, 필드 순서를 변경해도 문제가 없다.
  • 되도록 직접 만든 생성자에 붙이자

결론

잘알고 사용하자

실무 프로젝트에서는 가급적 @Getter, @Setter, @ToString 만 사용하고 그 외의 것들 사용은 자제하거나 매뉴얼을 잘 읽어보고서 보수적으로 사용한다.

@EqualsAndHashCode는 Immutable 필드만 명시적으로 지정하면서 자제해서 사용하거나 가급적 IDE 코드 제너레이션등을 통해 코드를 직접 만든다.

CATALOG
  1. 1. Lombok 에너테이션 각 장단점
  2. 2. 왜?
    1. 2.1. AllArgsConstructor
      1. 2.1.1. 발생할수있는 문제
    2. 2.2. RequiredArgsConstructor
      1. 2.2.1. 발생할수있는 문제
    3. 2.3. EqualsAndHashCode
      1. 2.3.1. 발생할수있는 문제
      2. 2.3.2. 참고로 hashCode()와 equals() 관계
    4. 2.4. NoArgsConstructor
      1. 2.4.1. 발생할수있는 문제
  3. 3. @Data 위험성
    1. 3.0.1. 발생할수있는 문제
  • 4. @Getter @Setter 주의해야한다. 이유는?
  • 5. 그 밖에 롬복 주로 사용하는것
    1. 5.1. @Getter
    2. 5.2. @Setter
    3. 5.3. @ToString
    4. 5.4. @Builder
  • 6. 결론