Lombok은 자바 컴파일 시점에서 반복적인 코드를 줄이기 위해 사용되는 라이브러리 중 하나이다. 특정 어노테이션을 사용하여 코드를 간소화하고 가독성을 높이는데 많은 도움이 된다.
우리는 Spring에서 Lombok을 사용하여 매우 편하고 빠르게 개발을 할 수 있다. 하지만 잘못 사용하면 위험성이 매우 높은 것이 바로 Lombok이다.
여러 강의 내용에서 @Data
어노테이션은 흔히 사용을 지양해야 하고, @Setter
어노테이션은 가급적 열어두지 말라는 말을 많이 들었다. 별 생각 없이 하지말라는건 하지 않았지만, 왜 사용하면 안 되는지 그 이유가 궁금했다.
지금부터 자주 사용되는 Lombok 어노테이션 종류와, 올바른 사용방법을 하나씩 알아보도록 하자.
@Getter
와 @Setter
이다. 이는 가장 많이 쓰이는 어노테이션으로 필드에 대한 getter 및 setter 메서드를 자동으로 생성해준다. @Getter
@Setter
public class Member {
private Long id;
private String name;
}
@Getter
어노테이션을 사용함으로써 필드 id, name의 getId()
, getName()
메서드를 자동으로 생성해주고, @Setter
어노테이션을 사용함으로써 setId()
, setName()
메서드가 자동으로 생성된다.@Getter
어노테이션의 경우 객체 필드를 읽는 동작이기 때문에 그다지 위험성이 있지는 않지만, @Setter
어노테이션의 경우 객체의 상태를 변경할 수 있는 동작이므로 객체의 안정성이 보장 받기는 힘들어진다.@Setter
어노테이션을 사용하지 않고, 따로 update
라는 의름의 메서드를 생성하여 구현한 방식이다. public void update(String name) {
this.name = name;
}
@NoArgsConstructor
어노테이션은 아무런 파라미터가 없는 생성자를 자동으로 생성해주고, @AllArgsConstructor
어노테이션은 모든 필드를 파라미터로 받는 생성자를 자동으로 생성해준다.@NoArgsConstructor
@AllArgsConstructor
public class Member {
private Long id;
private String name;
// @NoArgsConstructor 동작 생략
public Member() {
}
// @AllArgsConstructor 동작 생략
public Member(Long id, String name {
this.id = id;
this.name = name;
}
}
@NoArgsConstructor
어노테이션은 단독 사용하기 보다는 접근 권한을 protected
두고 외부에서 무분별한 객체 생성을 막는 방법으로 사용하는 것이 좋다.private
말고 protected
으로 열어두길 권장하고 있다. @NoArgsConstructor (access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Member {
private Long id;
private String name;
}
@AllArgsConstructor
어노테이션 사용은 지양해야 한다. 이는 매우 편리하게 생성자를 만들어주지만, 별 생각없이 사용할 경우 치명적인 오류를 발생시킬 수 있다. private Long id;
private String name;
private String location; // 추가된 필드
Member member = new Member(1, "jeondui", "Chuncheon"); // 올바른 순서
Member member = new Member(1, "Chuncheon", "jeondui"); // 잘못된 순서
@ToString
, @EqualsAndHashCode
, @Getter
, @Setter
, @RequiredArgsConstructor
를 모두 포함하는 어노테이션이다. 한 마디로 올인원이다. 강력한 어노테이션인 만큼 그에 따른 부작용도 많다.@ToString
어노테이션에 대해 추가로 말해 보겠다.@ToString
어노테이션은 필드 값들에 대한 ToString 메서드를 자동 생성해주는 기능인데, 만약 두 객체가 다대일 양방향 연관관계라고 가정한다면, 이때 ToString을 호출할시 서로 무한 순환 참조가 되어 stackoverflow가 발생한다.@ToString(exclude = "member")
처럼 옵션을 사용해서 특정 항목을 제외시키는 방법을 사용할 수 있다.@Data
어노테이션은 여러 위험성이 존재하므로 사용을 지양하는 것이 좋다.@Builder
어노테이션을 사용하여 의미 있는 객체를 생성할 수 있다.
public class Member {
private Long id;
private String name;
@Builder
public Member(Long id, String name {
this.id = id;
this.name = name;
}
}
// builder를 이용하여 객체 생성
Member member = Member.builder()
.id(1)
.name("jeondui")
.build();
지금까지 Lombok의 자주 사용되는 어노테이션 종류와 올바른 사용방법에 대해 알아보았다. 이제 실제로 엔티티 클래스를 Lombok 어노테이션을 사용하여 만들어보자.
@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(name = "member")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "member_id", nullable = false)
private Long id;
@Column(name = "member_name")
private String name;
@Builder
public Member(Long id, String name) {
this.id = id;
this.name = name;
}
public void update(String name) {
this.name = name;
}
}
@Data
, @Setter
, @AllArgsConstructor
어노테이션을 사용하지 않고, 빌더를 이용하여 의미 있고 안전한 객체 생성을 할 수 있게 되었다.
지금까지 Lombok에서 제공하는 유용한 어노테이션에 대해 알아보았다.
아무 생각 없이 편리하다고 무작정 사용하는 것 보다는, 올바른 사용 방법과 위험성을 인지하고 나의 상황에 알맞게 활용하는 것이 중요한 것 같다.
https://www.nowwatersblog.com/springboot/springstudy/lombok
https://dev-jhl.tistory.com/entry/Lombok-올바른-Lombok-사용법-Builder