티스토리 뷰
1. 들어가며
Lombok는 자바에서 작성해야 하는 boilerplate code(ex. getter/setter, constructor, toString)를 어노테이션을 통해서 자동으로 생성해주는 라이브러리입니다.
코드 자체가 더 간결해져 가독성도 높아지고 더 빠르게 개발할 수 있는 장점이 있습니다. 하지만, Lombok 사용 시 주의가 필요합니다. (참조 : Lombok Pitfall) 그래서 올바로 알고 주의해서 사용하기를 권장합니다. 이 포스팅에서는 자주 사용하는 어노테이션 위주로 설명하도록 하겠습니다.
2. 환경 설정
아래 환경 기반으로 코드가 작성되어 있습니다. IDE에서 Lombok 플러그인을 설치해야 어노테이션이 인식됩니다.
- OS: Mac OS
- IDE: Intelij
- Java : JDK 11
- Source code : github
- Software management tool : Maven
- IDE Plugin
-
Lombok Plugin
- Java Bytecode Decompiler : Enable - class 파일을 decompile 해서 소스를 볼 수 있다
pom.xml 파일에 lombok dependency를 추가해줍니다.
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> </dependency>
3. 대표적인 예제
자주 사용하는 어노테이션 위주로 살펴보도록 하겠습니다.
- @NonNull
- @Getter, @Setter
- @ToString
- @AllArgsConstructor, @AllArgsConstructor, @NoArgsConstructor
- @EqualsAndHashCode
- @Builder
- @Data
- @Slf4j, @Log, @Log4j, @Log4j2
- Lombok Configuration
@NonNull
메서드나 생성자 인자에 @NunNull 어노테이션을 추가하면 Lombok가 null 체크 구문을 생성해줍니다.
Lombok 사용 |
바닐라 자바 |
public class NonNullExample extends Something { private String name; public NonNullExample(@NonNull Person person) { super("Hello"); this.name = person.getName(); } } |
public class NonNullExample extends Something { private String name; public NonNullExample(@NonNull Person person) { super("Hello"); if (person == null) { throw new NullPointerException("person is marked @NonNull but is null"); } else { this.name = person.getName(); } } } |
위와 같이 바닐라 버전의 자바 소스를 보고 싶다면 IDE에서 Java Bytecode Decompiler 플러그인 활성화 이후 해당 class를 클릭하면 소스코드를 직접 확인할 수 있습니다.
@Getter, @Setter
클래스 필드에 대한 getter와 setter 메서드를 생성해주고 여러 옵션으로 다양한 코드를 자동생성할 수 있습니다. Setter는 필드가 final이 아닌 필드에 대해서 메서드가 생성됩니다.
- 클래스 전체에 적용
- 각 클래스 필드에 적용
- 메서드의 접근제어자 변경
- @Setter(AccessLevel.PROTECTED)
- 메서드 체이닝 (setter)
- @Accessors(chain = true)
Lombok 사용 |
바닐라 자바 |
@Getter @Setter public class Person { String name; int age; } |
public class Person { String name; int age; public Person() { } public String getName() { return this.name; } public int getAge() { return this.age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } |
//접근 제어자 public class PersonAccessLevel { @Getter @Setter String name; @Setter(AccessLevel.PROTECTED) int age; } |
public class PersonAccessLevel { String name; int age; public PersonAccessLevel() { } public String getName() { return this.name; } public void setName(String name) { this.name = name; } protected void setAge(int age) { this.age = age; } } |
//메서드 체이닝 @Setter @Accessors(chain = true) public class PersonSetterChain { String name; int age; } |
public class PersonSetterChain { String name; int age; public PersonSetterChain() { } public PersonSetterChain setName(String name) { this.name = name; return this; } public PersonSetterChain setAge(int age) { this.age = age; return this; } } |
@ToString
클래스의 toString 메서드를 자동으로 생성해주고 옵션을 주어 toString에 제외 시킬 필드 속성도 지정할 수 있습니다.
- 메서드에서 제외시킬 필드 지정
- @ToString.Exclude
- 메서드에서 추가하고 싶은 필드 지정
Lombok 사용 |
바닐라 자바 |
@ToString public class Person { String name; int age; } |
public class Person { String name; int age; public Person() { } public String toString() { return "Person(name=" + this.name + ", age=" + this.age + ")"; } } |
@ToString public class PersonExclude { @ToString.Include String name; @ToString.Exclude int age; } |
public class PersonExclude { String name; int age; public PersonExclude() { } public String toString() { return "PersonExclude(name=" + this.name + ")"; } } |
@EqualsAndHashCode
equals()와 hashCode()를 자동 생성해주는 어노테이션입니다.
- 제외시킬 필드 지정
- @EqualsAndHashCode.Exclude
바닐라 자바 코드가 너무 길어서 간출렸습니다. 실제 코드는 컴파일된 클래스 파일으로 확인해보세요.
Lombok 사용 |
바닐라 자바 |
@EqualsAndHashCode public class Person { String name; int age; } |
public class Person { String name; int age; public Person() { } public boolean equals(Object o) { …. } protected boolean canEqual(Object other) { return other instanceof Person; } public int hashCode() { int PRIME = true; int result = 1; Object $name = this.name; int result = result * 59 + ($name == null ? 43 : $name.hashCode()); result = result * 59 + this.age; return result; } } |
@EqualsAndHashCode public class PersonExclude { String name; @EqualsAndHashCode.Exclude int age; } |
public class PersonExclude { String name; int age; public PersonExclude() { } public boolean equals(Object o) { …. } protected boolean canEqual(Object other) { return other instanceof PersonExclude; } public int hashCode() { int PRIME = true; int result = 1; Object $name = this.name; int result = result * 59 + ($name == null ? 43 : $name.hashCode()); return result; } } |
@NoArgsConstructor, @AllArgsConstructor, @RequiredArgsContructor
생성자를 자동으로 생성해주는 어노테이션입니다. 필드 선언순서에 따라 생성자 인자가 정해집니다. 나중에 리펙토링을 하게 되면 인자 순서가 변경될 수 있다는 점을 기억하면 좋을 것 같습니다.
- NoArgsConstructor : 인자 없는 생성자
- AllArgsConstructor : 모든 필드를 인자로 받는 생성자
- RequiredArgsContructor(staticName=“of") : static factory 메서드를 생성함
Lombok 사용 |
바닐라 자바 |
@NoArgsConstructor public class PersonNoArgs { String name; int age; } |
public class PersonNoArgs { String name; int age; public PersonNoArgs() { } } |
@RequiredArgsConstructor(staticName = "of") @AllArgsConstructor(access = AccessLevel.PROTECTED) public class PersonArgs { String name; int age; } |
public class PersonArgs { String name; int age; private PersonArgs() { } public static PersonArgs of() { return new PersonArgs(); } protected PersonArgs(String name, int age) { this.name = name; this.age = age; } } |
@Data
@Data 어노테이션은 아래 모든 어노테이션이 적용되는 어노테이션입니다.
- @ToString
- @EqualsAndHashCode
- @Getter, @Setter
- @RequiredArgsConstructor
Lombok 사용 |
바닐라 자바 |
@Data public class Person { String name; int age; } |
public class Person { String name; int age; public Person() { } public String getName() { return this.name; } ... public String toString() { return "Person(name=" + this.getName() + ", age=" + this.getAge() + ")"; } } |
@Builder
어노테이션 하나로 Builder Pattern을 생성해줍니다. 빌더 패턴은 여러 설정하고 객체를 만들어주는 패턴입니다. 더 자세한 내용은 아래 참조를 확인해주세요.
Lombok 사용 |
바닐라 자바 |
@Builder @ToString public class Car { private int wheels; private String color; public static void main(String[] args) { System.out.println(Car.builder().color("red").wheels(2).build()); } } /* OUTPUT Car(wheels=2, color=red) */ |
public class Car { private int wheels; private String color; public static void main(String[] args) { System.out.println(builder().color("red").wheels(2).build()); } Car(int wheels, String color) { this.wheels = wheels; this.color = color; } public static Car.CarBuilder builder() { return new Car.CarBuilder(); } public String toString() { return "Car(wheels=" + this.wheels + ", color=" + this.color + ")"; } public static class CarBuilder { private int wheels; private String color; CarBuilder() { } public Car.CarBuilder wheels(int wheels) { this.wheels = wheels; return this; } public Car.CarBuilder color(String color) { this.color = color; return this; } public Car build() { return new Car(this.wheels, this.color); } public String toString() { return "Car.CarBuilder(wheels=" + this.wheels + ", color=" + this.color + ")"; } } } |
@Slf4j, (@Log, @Log4j, @Log4j2, etc)
원하는 로깅 프레임워크를 선택해서 선언하면 보다 쉽게 로그를 사용할 수 있습니다.
Lombok 사용 |
바닐라 자바 |
@Builder @ToString public class Car { private int wheels; private String color; public static void main(String[] args) { System.out.println(Car.builder().color("red").wheels(2).build()); } } /* OUTPUT
Car(wheels=2, color=red)
*/
|
public class Car { private int wheels; private String color; public static void main(String[] args) { System.out.println(builder().color("red").wheels(2).build()); } Car(int wheels, String color) { this.wheels = wheels; this.color = color; } public static Car.CarBuilder builder() { return new Car.CarBuilder(); } public String toString() { return "Car(wheels=" + this.wheels + ", color=" + this.color + ")"; } public static class CarBuilder { private int wheels; private String color; CarBuilder() { } public Car.CarBuilder wheels(int wheels) { this.wheels = wheels; return this; } public Car.CarBuilder color(String color) { this.color = color; return this; } public Car build() {] return new Car(this.wheels, this.color); } public String toString() { return "Car.CarBuilder(wheels=" + this.wheels + ", color=" + this.color + ")"; } } } |
Lombok Configuration
Lombok에서 제공하는 기능에 대해서 사용하지 못하게 하는 설정등이 가능합니다. 프로젝트 루트에 lombok.config 파일을 생성해서 원하는 설정를 key=value 형식으로 작성하면 됩니다. 구체적인 설정은 해당 Lombok Configuration system을 참조해주세요.
예 - 설정(@NonNull 사용 금지)
lombok.nonNull.flagUsage=error
IDE에서는 표시되지 않지만, 컴파일시 오류가 발생합니다.
4. 참고
- Lombok
- Lombok Pitfall
- Lombok Config
- Builder 패턴
'java' 카테고리의 다른 글
자바 keystore에 SSL 인증서 import 하기 (0) | 2019.01.09 |
---|---|
Java Jayway JsonPath 사용법 (0) | 2019.01.09 |
자바 커스텀 어노테이션 만들기 (0) | 2018.11.18 |
맥 환경에서 여러 JDK 버전 설치하고 변경하기 (0) | 2018.11.11 |