Post View

반복되는 코드, lombok으로 줄여보자!

스프링으로 개발을 하다보면 Model class를 만들어야 하는 경우가 자주 있습니다.
그런데 실제 사용하는 인스턴스 변수를 작성하는 것 보다 훨씬 더 많은 getter와 setter, toString, equlas, hashcode 등의 메서드들을 작성하는게 귀찮더라구요.
물론 eclipse를 사용한다면 해당 메서드 들을 쉽게 만들어줄 수 있지만 도중에 인스턴스 변수명이 바뀌거나 하는 경우 메서드들을 다시 만들거나 일일이 수정해야 하므로 더욱 귀찮아지죠.

그래서 이번에는 그러한 귀찮음을 하나의 어노테이션으로 해결해주는 lombok(https://projectlombok.org)이란 라이브러리를 사용해보았습니다.

lombok은 자바 개발 시 반복되어 나타나는 코드 패턴을 일부 대체해주는 기능을 합니다.
주요 기능은 Model class에 작성되어지는 getter, setter, toString, hashcode, equals 메서드 작성해주는 기능이 있으며,
객체 사용 후 자동으로 close 처리를 해주는 Cleanup 어노테이션이나, sychronized 처리 시 flag 변수를 없애주는 Synchronized 어노테이션 등 주로 사용되지만 개발자가 작성하기 귀찮은 반복적인 코드를 작성해야하는 곳에 대신 사용됩니다.

제 경우는 아직은 Model class에서 사용하는 어노테이션을 주로 쓰고 있지만, 이것만으로도 충분히 편리하더라구요.

사용방법은 먼저 lombok.jar 파일을 다운로드(https://projectlombok.org/download) 받아줍니다.
그 다음, 다운로드 받은 경로로 이동해서 아래의 명령을 실행합니다.

java -jar lombok.jar

실행하게 되면 아래의 이미지처럼 Project Lombok Installer 창이 나타납니다.

여기서 사용하는 IDE를 선택한 뒤 Install / Update를 눌러줍니다.
만약 이미 lombok이 설치된 IDE의 경우 파일명 옆의 고추 아이콘...이 나타납니다.

설치가 완료되었다면 Install successful 화면이 나타나며 Quit Installer 버튼을 눌러서 종료해주고,
해당 IDE를 실행합니다.

IDE를 실행했다면 mvnrepository에서 lombok을 검색하여 dependency를 복사한 뒤 pom.xml에 추가해줍니다.
https://mvnrepository.com/artifact/org.projectlombok/lombok에서 버전을 찾아 추가해주시면 됩니다.

위의 코드는 lombok이 적용된 코드입니다.
오른쪽의 Outline 화면을 보면 실제 입력되지 않은 getter와 setter, equlas, hashCode, toString 등의 메서드가 표시되는 것을 볼 수 있습니다.

이 코드를 lombok 없이 작성한다면 아래와 같이 작성해야합니다.

package net.kurien.blog.module.comment.vo;

import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;

public class Comment {
    private int commentNo;
    private int postNo;
    private int parentCommentNo;
    private int commentOrder;
    private int commentDepth;
    private String author;
    private String password;
    private String comment;
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date writeTime;
    private String writeIp;
    private String deleteYn;
    
    public int getCommentNo() {
        return commentNo;
    }
    public void setCommentNo(int commentNo) {
        this.commentNo = commentNo;
    }
    public int getPostNo() {
        return postNo;
    }
    public void setPostNo(int postNo) {
        this.postNo = postNo;
    }
    public int getParentCommentNo() {
        return parentCommentNo;
    }
    public void setParentCommentNo(int parentCommentNo) {
        this.parentCommentNo = parentCommentNo;
    }
    public int getCommentOrder() {
        return commentOrder;
    }
    public void setCommentOrder(int commentOrder) {
        this.commentOrder = commentOrder;
    }
    public int getCommentDepth() {
        return commentDepth;
    }
    public void setCommentDepth(int commentDepth) {
        this.commentDepth = commentDepth;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String comment) {
        this.comment = comment;
    }
    public Date getWriteTime() {
        return writeTime;
    }
    public void setWriteTime(Date writeTime) {
        this.writeTime = writeTime;
    }
    public String getWriteIp() {
        return writeIp;
    }
    public void setWriteIp(String writeIp) {
        this.writeIp = writeIp;
    }
    public String getDeleteYn() {
        return deleteYn;
    }
    public void setDeleteYn(String deleteYn) {
        this.deleteYn = deleteYn;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((author == null) ? 0 : author.hashCode());
        result = prime * result + ((comment == null) ? 0 : comment.hashCode());
        result = prime * result + commentDepth;
        result = prime * result + commentNo;
        result = prime * result + commentOrder;
        result = prime * result + ((deleteYn == null) ? 0 : deleteYn.hashCode());
        result = prime * result + parentCommentNo;
        result = prime * result + ((password == null) ? 0 : password.hashCode());
        result = prime * result + postNo;
        result = prime * result + ((writeIp == null) ? 0 : writeIp.hashCode());
        result = prime * result + ((writeTime == null) ? 0 : writeTime.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Comment other = (Comment) obj;
        if (author == null) {
            if (other.author != null)
                return false;
        } else if (!author.equals(other.author))
            return false;
        if (comment == null) {
            if (other.comment != null)
                return false;
        } else if (!comment.equals(other.comment))
            return false;
        if (commentDepth != other.commentDepth)
            return false;
        if (commentNo != other.commentNo)
            return false;
        if (commentOrder != other.commentOrder)
            return false;
        if (deleteYn == null) {
            if (other.deleteYn != null)
                return false;
        } else if (!deleteYn.equals(other.deleteYn))
            return false;
        if (parentCommentNo != other.parentCommentNo)
            return false;
        if (password == null) {
            if (other.password != null)
                return false;
        } else if (!password.equals(other.password))
            return false;
        if (postNo != other.postNo)
            return false;
        if (writeIp == null) {
            if (other.writeIp != null)
                return false;
        } else if (!writeIp.equals(other.writeIp))
            return false;
        if (writeTime == null) {
            if (other.writeTime != null)
                return false;
        } else if (!writeTime.equals(other.writeTime))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Comment [commentNo=" + commentNo + ", postNo=" + postNo + ", parentCommentNo=" + parentCommentNo
                + ", commentOrder=" + commentOrder + ", commentDepth=" + commentDepth + ", author=" + author
                + ", password=" + password + ", comment=" + comment + ", writeTime=" + writeTime + ", writeIp="
                + writeIp + ", deleteYn=" + deleteYn + "]";
    }
}

이 코드들을 Data 어노테이션 하나로 끝나니 편리한 점도 있지만, 인스턴스 변수만 남게 되니 보기가 편해서 좋은 것 같습니다.
인스턴스 변수가 바뀌어도 추가 수정을 하지 않아도 된다는 점도 좋구요.

대신 lombok을 쓰시면 한가지 조심하셔야 할게 있는데요.
lombok이 설치된 IDE가 아닌 다른 IDE로 실행하면 Data어노테이션이 작동하지 않아서 오류가 발생하니, lombok을 쓴다면 다른 환경의 IDE를 사용하실 때 다시 설치해야한다는 점을 기억해두세요!

롬복에 대한 자세한 내용은 아래의 주소에서 확인하시기 바랍니다.
https://projectlombok.org/features/all

영어로 되어있지만 Lombok annotated code(lombok 어노테이션을 이용한 코드)와 Equivalent Java source code(동일한 기능의 자바 코드)가 잘 나누어져 있어서 코드만 보더라도 쉽게 이해가 가능하니 걱정하지 마시고 읽어보시기 바랍니다.

Comments