Java - Lombok 기초
Lombok 이란
Lombok이란 Java의 라이브러리로 반복되는 메소드를 Annotation을 사용해서 자동으로 작성해주는 라이브러리다. 보통 DTO나 Model, Entity의 경우 여러 속성이 존재하고 이들이 가지는 프로퍼티에 대해서 Getter나 Setter, 생성자 등을 매번 작성해줘야 하는 경우가 많은데 이러한 부분을 자동으로 만들어주는 라이브러리라고 할 수 있다.
val
val형을 사용해 변수를 정의하면 대입된 값으로부터 형추론을 해 줍니다.
val은 final형이므로, 재대입은 할 수 없습니다.
import lombok.val;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
// val 문자열형을 대입하고 있으므로 val 은 String형을 추론할 수있다.
val name = "SEO";
// final형이므로 재대입을 불가하다.型なので再代入は不可
// name = "BEO";
val map = new HashMap<String, Integer>();
map.put("HEO", 10);
}
}
다만, Java10으로부터 도입된 var에 final 수식하는 것으로 같은 기능을 실현할 수 있으므로 별 차례가 없는 것이 아닐까 생각합니다.
@NonNull
@NonNull은 메소드나 생성자의 파라미터에 부여하는 것으로 자동적으로 NULL 체크를 실시해 줍니다.
import lombok.NonNull;
public class NonNullSample {
public void execute(@NonNull String name) {
System.out.println(name.toUpperCase());
}
}
위의 샘플의 경우, name 파라미터가 null 의 경우에 NullPointerException 가 Exception 됩니다.
constructor 의 인수의 경우는 this 나 super 가 명시적으로 실행되어, 그 후에 null 체크가 행해집니다.
덧붙여서 lombok에는 디폴트의 거동을 설정하기 위한 기능이 있어, 프로젝트의 폴더 바로 아래에 lombok.config라는 파일을 배치하는 것으로 사용할 수 있습니다.
예를 들어, @NonNull 어노테이션은 NullPointerException을 표준으로 throw하지만 이 동작을 사용자 정의할 수 있습니다.
@Cleanup
로컬 변수에 @ Cleanup을 부여하여 해당 변수가 속한 범위를 벗어날 때 자동으로 close 메소드를 실행합니다
import lombok.Cleanup;
public class CleanupSample {
public void execute() {
@Cleanup var hoge = new Hoge();
hoge.execute();
}
// ↓의 코드가 작성된다.
/*
public void execute() {
Hoge hoge = new Hoge();
try {
hoge.execute();
} finally {
if (hoge != null) {
hoge.close();
}
}
}
*/
public static class Hoge {
public void execute() {
System.out.println("HOGE");
}
public void close() {
System.out.println("Close HOGE");
}
}
@Getter
@Getter, @Setter 어노테이션은 클래스 필드에 부여하여 getter, setter를 자동 생성합니다.
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class User {
@Getter
@Setter
private String name;
// ↓ 자동작성된다.
/*
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
*/
// AccessLevel을 지정하는 것으로 프로텍트로 작성가능
@Setter(AccessLevel.PROTECTED)
private int age;
// ↓ 자동작성된다.
/*
protected void setAge(int age) {
this.age = age;
}
*/
@Getter
private boolean invalid;
// ↓ 자동작성(boolean의 경우 isXX가 된다.)
/*
public boolean isInvalid() {
return this.invalid;
}
*/
}
또 클래스로 지정했을 경우는 그 클래스의 모든 비static 필드에 대해서 getter 및 setter 를 자동 생성합니다.
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@Getter @Setter
public class Item {
private String itemId;
private String itemName;
// getter, setter를 작성하기 싫은 경우 개별로AccessLevel.NONE을 지정
@Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
private boolean hidden;
}
@ToString
@ToString은 클래스에 부여하여 toString 메소드를 자동으로 생성할 수 있습니다.
import lombok.ToString;
@ToString
public class ToStringSample {
private String name;
private int age;
// ↓자동작성되는 코드
/*
public String toString() {
return "ToStringSample(name=" + this.name + ", age=" + this.age + ")";
}
*/
}
@ToString은 예제와 같이 기본적으로 클래스 이름과 쉼표로 구분 된 필드 이름과 값을 생성하지만 includeFieldNames 매개 변수를 false로 설정하면 필드 이름이 출력되지 않습니다.
import lombok.ToString;
@ToString(includeFieldNames = false)
public class ToStringSample {
private String name;
private int age;
// ↓자동작성되는 코드
/*
public String toString() {
return "ToStringSample(" + this.name + ", " + this.age + ")";
}
*/
}
주의해야 하는 것은 클래스의 필드에 자신을 보관 유지하는 클래스가 있었을 경우는, 무한 루프가 되어 버립니다. 이 경우 대상 필드를 toString에서 제외해야합니다.
@ToString(exclude = "employees") // (1) 제외할 필드를 지정(복수지정가능)
public class Company {
private int id;
private String companyName;
private List<Employee> employees;
}
@ToString
public class Employee {
private String employeeNo;
private String name;
@ToString.Exclude // (2) 제외할 필드에 ToString.Exclude애노테이션을 붙인다.
private Company company;
}
필드를 제외하려면 @ToString 어노테이션에 exclude 속성을 지정하는 방법(1)과 제외할 필드에 @ToString.Exclude 어노테이션을 부여하는 방법(2)의 두 가지 설정 방법이 있습니다.
또한 제외와는 반대로 toString에 포함시킬 필드를 지정하는 것도 가능합니다.
@ToString(of = {"id", "companyName"}) // (1) toString에 포한하는필드를 지정(복수 지정 가능)
public class Company {
private int id;
private String companyName;
private List<Employee> employees;
}
@ToString(onlyExplicitlyIncluded = true) // (2) ToString.Include 부여되는 필드만을 포함되도록 지정
public class Employee {
@ToString.Include // (2) 대상에포함하는필드에ToString.Include어노테이션을부여
private String employeeNo;
@ToString.Include
private String name;
private Company company;
}
@ToString 어노테이션에 of 속성을 지정하는 방법(1)과 대상에 포함하는 필드에 @ToString.Include 어노테이션을 부여하는 방법(2)의 2 종류의 설정 방법이 있습니다.
@ToString 어노테이션에 callSuper 속성을 true로 지정하여 수퍼 클래스 toString의 결과를 포함할 수 있습니다.
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
@NoArgsConstructor : 인수없는 생성자
@NoArgsConstructor는 인수 없는 생성자를 자동으로 생성합니다.
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class ConstructorSample {
// ↓ 자동작성되는 코드
/*
public ConstructorSample() {
}
*/
}
@RequiredArgsConstructor : 필수 필드 생성자
@RequiredArgsConstructor 는 final 지정된 필드를 인수로 가지는 생성자를 자동 생성합니다.
import lombok.RequiredArgsConstructor;
import java.time.LocalDate;
@RequiredArgsConstructor
public class ConstructorSample {
private final String name;
private int age;
private final LocalDate birthday;
// ↓ 자동 작성되는 코드
/*
public ConstructorSample(String name, LocalDate birthday) {
this.name = name;
this.birthday = birthday;
}
*/
}
@AllArgsConstructor : 모든 필드 생성자
@AllArgsConstructor 는 모든 비static 필드를 인수에 가지는 constructor 을 자동 생성합니다.
import lombok.AllArgsConstructor;
import java.time.LocalDate;
@AllArgsConstructor
public class ConstructorSample {
private final String name;
private int age;
private final LocalDate birthday;
// ↓ 자동 작성되는 코드
/*
public ConstructorSample(String name, int age, LocalDate birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
*/
}
@Data
@Data는 앞서 소개한 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RuquiredArgsConstructor를 정리한 어노테이션이 됩니다.
아마도 lombok에서이 주석이 가장 많이 사용되는 것은 아닐까 생각합니다.
import lombok.Data;
import java.time.LocalDate;
@Data
public class DataSample {
private final String name;
private int age;
private final LocalDate birthday;
}
끝까지 읽어 주셔서 감사합니다.