새로운 블로그로 이전하였습니다!

Lombok

Lombok 동작 순서

  1. javac 가 프로그래밍 언어로 작성 된 소스 코드를 파싱하여 AST 를 만듭니다.
  2. Lombok 의 AnnotationProcessor 가 컴파일중 AST를 수정 및 추가 생성 합니다.
  3. javac 는 AnnotationProcessor에 의해 수정된 AST를 기반으로 class 파일을 생성합니다.

 

AST ( abstract syntax tree, 추상 구문 트리 )

프로그래밍 언어로 작성된 소스 코드를 컴파일러가 각각 의미별로 분류하여 컴퓨터가 이해할 수 있게 "abstract syntax" 구조로 만들어낸 중간 결과물 입니다.

abstract syntax : 프로그래밍 언어의 문법 규칙

  • ex JAVA) public String methodName( String str ) { ... }
  • 접근자 타입 메소드명 ( 매개변수 타입, 매개변수명 ) 의 순서 등등

 

예를 들어 아래의 코드를 컴파일러가 AST로 만들어낼 경우 사진과 같은 AST가 만들어 집니다.

while b ≠ 0
	if a > b
		a := a − b
	else
		b := b − a
	return a

 

Annotation Processor

자바 컴파일러 플러그인의 일종으로 컴파일 단계에서 Annotation 으로 정의된 소스 코드를 실행시켜줍니다.

이를 통해 컴파일 과정에서 에러를 검출하거나 소스 코드 변경, .java, .class 파일 생성 등의 기능을 수행할 수 있습니다.

 

컴파일 결과 확인

Lombok Annotation 으로 만든 결과물도 디컴파일러를 통해 확인이 가능합니다.

프로젝트 경로/build/classes/java/ 이후 동일 경로로 들어가면 컴파일된 소스 코드를 확인할 수 있습니다.

예시로 자주 사용하는 Annotation 4종으로 만들어봤습니다.

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LombokTestDto {
    private String str;
    private int number;
    private List<String> list;
}

결과

public class LombokTestDto {
    private String str;
    private int number;
    private List<String> list;

    public static LombokTestDtoBuilder builder() {
        return new LombokTestDtoBuilder();
    }

    public String getStr() {
        return this.str;
    }

    public int getNumber() {
        return this.number;
    }

    public List<String> getList() {
        return this.list;
    }

    public void setStr(String str) {
        this.str = str;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof LombokTestDto)) {
            return false;
        } else {
            LombokTestDto other = (LombokTestDto)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (this.getNumber() != other.getNumber()) {
                return false;
            } else {
                Object this$str = this.getStr();
                Object other$str = other.getStr();
                if (this$str == null) {
                    if (other$str != null) {
                        return false;
                    }
                } else if (!this$str.equals(other$str)) {
                    return false;
                }

                Object this$list = this.getList();
                Object other$list = other.getList();
                if (this$list == null) {
                    if (other$list != null) {
                        return false;
                    }
                } else if (!this$list.equals(other$list)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof LombokTestDto;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        result = result * 59 + this.getNumber();
        Object $str = this.getStr();
        result = result * 59 + ($str == null ? 43 : $str.hashCode());
        Object $list = this.getList();
        result = result * 59 + ($list == null ? 43 : $list.hashCode());
        return result;
    }

    public String toString() {
        return "LombokTestDto(str=" + this.getStr() + ", number=" + this.getNumber() + ", list=" + this.getList() + ")";
    }

    public LombokTestDto(String str, int number, List<String> list) {
        this.str = str;
        this.number = number;
        this.list = list;
    }

    public LombokTestDto() {
    }

    public static class LombokTestDtoBuilder {
        private String str;
        private int number;
        private List<String> list;

        LombokTestDtoBuilder() {
        }

        public LombokTestDtoBuilder str(String str) {
            this.str = str;
            return this;
        }

        public LombokTestDtoBuilder number(int number) {
            this.number = number;
            return this;
        }

        public LombokTestDtoBuilder list(List<String> list) {
            this.list = list;
            return this;
        }

        public LombokTestDto build() {
            return new LombokTestDto(this.str, this.number, this.list);
        }

        public String toString() {
            return "LombokTestDto.LombokTestDtoBuilder(str=" + this.str + ", number=" + this.number + ", list=" + this.list + ")";
        }
    }
}
복사했습니다!