Lombok이란?
Lombok은 Getter, Setter, ToString과 같은 메서드들을 간편하게 사용할 수 있게해주는 어노테이션기반 JAVA의 라이브러리입니다. 물론 IDE를 사용해 Getter, Setter 등의 메서드들을 손쉽게 생성할 수 있지만 멤버변수가 증가하면 증가할 수 록 코드의 양이 많아지고 복잡해지게 됩니다. Lombok은 이러한 것을 어노테이션을 이용해 개발자가 실제 구현한 코드에는 보이지 않지만 컴파일이 될 때 해당 메서드들이 자동으로 생성이 되는 과정을 통해 돌아가게 됩니다.
Lombok 사용하기
의존성 추가
- Spring Boot를 사용할 시 프로젝트 생성할 때 추가해도 되지만 그렇지 않다면 아래의 의존성을 추가해주어야한다.
compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok'
IntelliJ
를 사용할 경우 다음과 같이 설정도 해주어야 합니다.Preferences - Build, Excution, Deployment - Compiler - Annotation Processors
에서Enable Annotation Processing
항목을 활성화시킨다.
@Getter와 @Setter
Lombok을 사용하지 않은
Person
클래스public class Person { private Long id; private String name; private int age; private String hobby; public Long getId() { return id; } public String getName() { return name; } public int getAge() { return age; } public String getHobby() { return hobby; } public void setId(Long id) { this.id = id; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setHobby(String hobby) { this.hobby = hobby; } }
Lombok을 사용한
Person
클래스@Getter @Setter public class Person { private Long id; private String name; private int age; private String hobby; }
위의 예가 살짝 극단적이기는 하지만 멤버변수가 단지 4개일 뿐인데 Lombok을 사용하지 않은 코드와 사용한 코드의 라인 수 가 확연이 차이나는 것을 확인할 수 있다. 하지만 무분별한 Getter와 Setter는 캡슐화를 위반할 수 있으므로 좋지 않다.
public class Person {
@Getter
private Long id;
@Getter
@Setter
private String name;
private int age;
private String hobby;
}
위의 코드에서는 id
와 name
은 외부에서 Get할 수 있지만 age
, hobby
의 경우는 get할 수 없다. 또한 name
만이 외부에서 Set을 할 수 있다. 이처럼 멤버변수마다 따로 지정을 할 수 있어 무분별한 Getter, Setter의 설정으로 캡슐화를 위반해 결합도 를 높일 수 있는 위험성을 낮출 수 있다.
@ToString 사용
객체를 원하는 형태의 String으로 나타내기 위하여
toString
이라는 메서드를 오버라이드하여 사용한다.public class Person { private Long id; private String name; private int age; private String hobby; @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", hobby='" + hobby + '\'' + '}'; } }
여기에 멤버변수가 빈번히 추가된다거나 멤버변수가 많아서 코드의 양이 늘어난다거나 할 수 있는데 이 또한 Getter나 Setter와 같이 Lombok이 어노테이션으로 지정만하면 자동으로 만들어준다.
@ToString public class Person { private Long id; private String name; private int age; private String hobby; }
만약
toString
을 사용하는데age
라는 값은 제외하고 보여주고 싶을 수 있는데 그럴때는 아래와 같이 사용할 수도 있다.@ToString(exclude = "age") public class Person { private Long id; private String name; private int age; private String hobby; }
또는
@ToString public class Person { private Long id; private String name; @ToString.Exclude private int age; private String hobby; }
생성자 생성하기
@NoArgsConstructor
Default 생성자를 추가해주는 어노테이션이다.
@AllArgsConstructor
모든 멤버변수를 인자로 가지는 생성자를 추가해주는 어노테이션이다.
@RequiredArgsConstructor
@NonNull 어노테이션으로 지정해 놓은 멤버변수를 인자로 가지는 생성자를 추가해주는 어노테이션이다.
@NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor public class Person { @NonNull private Long id; @NonNull private String name; private int age; private String hobby; }
위의 코드에서는 세 가지의 생성자가 존재하는 것과 같은 코드라고 볼 수 있다.
public Person() { } public Person(Long id, String name) { this.id = id; this.name = name; } public Person(Long id, String name, int age, String hobby) { this.id = id; this.name = name; this.age = age; this.hobby = hobby; }
@EqualsAndHashCode 사용하기
객체의 같음을 판단해주는 equals와 해시코드를 만들어주는 hashCode 함수를 오버라이드 하지않아도 Lombok이 자동으로 추가를 해준다. 따라서 비교해야할 멤버변수가 늘어난다거나해도 코드를 따로 변경하지않고 어노테이션만 있다면 번거롭지 않게 코딩을 할 수 있다.
public class Person { private Long id; private String name; private int age; private String hobby; @Override public boolean equals(Object object){ if(object == null) { return false; } Person person = (Person) object; if(!person.getName().equals(this.name)){ return false; } if(person.getAge() != this.age) { return false; } return true; } @Override public int hashCode() { return (name + age).hashCode(); } }
- 기존에 위의 코드처럼 equals()와 hashCode() 오버라이드하여 사용하여야했다. 그러나 지금 위의 코드는 hobby의 같음 여부와 해시코드를 생성하는 곳에서 사용하지 않는다. 따라서 내용이 같은 객체 두 개를 생성하여 비교해보면 다르다는 결과를 얻을 수 있을 것이다. 이 문제를 해결하기 위해서는 두 메서드에 모두 hobby라는 값을 추가해주어야한다.
@EqualsAndHashCode public class Person { private Long id; private String name; private int age; private String hobby; }
- 그러나 @EqualsAndHashCode 어노테이션을 사용하면 위의 코드와 같이 깔끔하게 해결을 할 수 있다.
@Data
* @see Getter * @see Setter * @see RequiredArgsConstructor * @see ToString * @see EqualsAndHashCode * @see lombok.Value */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Data { // 생략 }
위의 코드는 @Data 어노테이션이 구현되어있는 코드이다. 위에서 볼 수 있듯이 @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode가 포함되어있는 것을 확인할 수 있다. 쉽게 말해 이 5개 어노테이션을 묶어서 파는 기획상품?이라고 표현할 수도 있을 것 같다.
하지만 @Data를 사용하면 무분별한 Setter의 남용으로 객체의 안전성을 보장받기 힘들고 @ToString으로 인한 양방향 연관관계시 순환 참조 문제와 같이 문제가 발생할 수 있어 지양하는 것이 좋다고 합니다.
@Builder
이 어노테이션 또한 Builder를 자동으로 만들어주는 어노테이션입니다.
이렇게 Lombok에 대하여 알아보았습니다. Lombok은 코드의 다이어트와 가독성 및 유지보수에 많은 도움이 될 수 있습니다. 하지만 편리한만큼 잘 못 사용하여 독이 될 수도 있다고 합니다. 따라서 객체를 생성하거나 메서드를 제공할 때 캡슐화나 응집도, 결합도 측면을 조금만 더 깊게 생각해보고 Lombok을 상황에 맞게 사용하는 것이 중요하다고 생각을 합니다.
'Programming > Java' 카테고리의 다른 글
[자바 프로그래밍] Lesson4 클래스 메소드와 필드 (0) | 2020.08.30 |
---|---|
[자바 프로그래밍] Lesson3 문자열과 패키지 (0) | 2020.08.29 |
[자바 프로그래밍] Lesson2 자바의 기초 (0) | 2020.08.17 |
[자바 프로그래밍] Lesson1 시작하기 (0) | 2020.08.16 |
[Java] Comparator를 사용한 2차원배열 정렬 (1) | 2020.01.12 |