본문 바로가기
프로그래밍/프로젝트

2. Lombok 사용과 고민

by 카프카뮈 2021. 1. 31.

저번 게시물에서는 프로젝트 컨벤션을 정하는 과정에 대해 이야기했다.

그 사이 깃헙 저장소도 만들었고, 저장소를 클론해 프로젝트 생성도 마무리했다.

원래는 Spring Initializer를 통한 프로젝트 생성에 대해 포스팅 해볼까도 싶었는데,

다시 생각해보니 그렇게 어려움을 겪은 적도 없고 나중에 수정하기도 쉬운 부분이라...

 

대신 이전 프로젝트에서 참 유용하게 사용했던, 하지만 조금씩 고민도 있었던 Lombok에 대해 이야기해보려 한다.


Lombok

롬복(링크)은 자바 개발자들의 필수 라이브러리(라고 많이 알려진)이자,

코드의 가독성과 양을 획기적으로 개선해 주는 라이브러리다.

롬복을 사용할 경우 우리가 Java로 객체를 만들면서 사용하는

다양한 형식의 생성자, Getter, Setter, toString 등을 어노테이션으로 대체할 수 있다.

게다 인텔리제이에서 Spring 프로젝트를 진행중인 내 기준으로, 설치도 매우 편리했다.

Gradle에 의존성을 추가해 주고, 인텔리제이에서 제공하는 플러그인을 깔면 오케이!!

Lombok의 사용 예시

다음과 같은 코드가 있다고 하자.

평범해 보이는 코드. 하지만 생성자나 Getter 때문에 길이가 길어진다.

위 코드를 보면, 기본 생성자와 모든 필드 변수를 포함하는 생성자가 일단 존재한다. 또한 Getter 역시 존재한다.

 - Entity이기 때문에, Jpa에서 이 클래스를 사용한다. 이때, Repository의 조회 로직에서 빈 생성자를 활용하므로 빈 생성자가 필수적으로 필요하다. (만약 빈 생성자를 빼먹으면, 시스템에서 에러를 출력한다.)

 - setter 메서드는 두지 않았다. 만약 setter 메서드가 존재할 경우 객체의 상태가 바뀔 위험이 있으므로,
    생성자를 통해 값을 주입하고 이후에는 값이 변경되지 않는다고 생각했다. 만약 값을 바꿔야 한다면, 새로운 객체를 만들면 된다!

 - 그러나 현실적인 타협으로 Getter는 사용하게 되었다.

 

위에 적힌 개념들은, 다른 Entity에도 똑같이 적용되는 내용이다.

그렇다면, 우리는 모든 Entity를 만들어 줄 때마다 생성자와 getter 코드를 넣어야 하는 것이다.

getter는 해당 값을 반환할 뿐이고 생성자는 비어있거나 값을 주입할 뿐인데,

이런 메서드가 존재하는지가 중요하지 내용은 중요치 않은 것이다.

 

이런 상황에서 Lombok의 사용은 우리의 코드를 아름답게 만들어준다.

위 코드의 본문에 있던 생성자/Getter를 어노테이션으로 대체!!

위 코드는 앞서 보여준 코드와 같은 기능을 수행한다. 여기서 우리는 다음과 같은 사실을 알 수 있다.

 - @Getter 어노테이션을 사용하는 것으로, 필드 변수들에 대한 Getter 메서드를 자동으로 생성할 수 있다.

 - @NoArgsConstructor 어노테이션을 사용하는 것으로, 인자가 없는 생성자를 자동으로 생성할 수 있다.

 - @AllArgsConstructor 어노테이션을 사용하는 것으로, 인자를 받아 필드에 대입하는 생성자를 자동으로 생성할 수 있다.

 

DTO도 마찬가지이다.

값 반환에 사용되는 DTO의 모습. 생성자와 Getter 때문에 코드 가독성이 떨어진다.

위의 도메인 클래스와 마찬가지로, Getter와 생성자가 필요하다.

게다, @RequestBody 어노테이션 사용시 비직렬화 로직때문에 빈 생성자도 필요하다

(이에 대해서는 아직 학습중이다. 설명이 잘 된 포스팅을 공유한다 : 링크

 

[SpringBoot] @RequestBody 에 들어가는 Object 는 No-Argument Constructor 가 존재해야 한다.

아래와 같이 @RestController 에 메소드가 있다고 생각해보자. @PostMapping public ResponseEntity getResDto(@RequestBody AccountReqDto dto){ return ResponseEntity.ok(AccountResDto.builder().email("test@..

blusky10.tistory.com

Lombok 사용을 통해, 핵심 로직만 남겨 가독성을 높일 수 있다.

위 코드 역시 앞서 소개한 코드와 같은 기능을 수행한다.

그러나 생성자와 Getter가 어노테이션으로 대체되어, 코드로 노출되지 않아 길이가 짧아진다.

또한 이 로직의 메인인 필드변수, 그리고 특수한 생성자
(서비스 레이어에서 도메인을 DTO로 변환할때 사용되는 생성자!)가 눈에 확 들어온다.


Lombok을 사용하면서 주로 사용했던 기능을 정리하여 소개하면, 다음과 같다.

- @Getter : 필드변수에 대한 Getter 메서드를 자동생성한다. 이름은 Get+변수이름 으로 지어진다.

- @NoArgsConstructor : 인자가 없는 기본 생성자 메서드를 자동생성한다.

- @AllArgsContructor : 모든 필드 변수를 인자로 가지는 생성자 메서드를 자동생성한다. 인자는 필드변수와 같은 형식/이름을 가진다.

- @RequiredArgsConstructor : Final로 지정된 필드 변수만 인자로 받아 대입해주는 생성자 메서드를 자동생성한다. 컨트롤러/서비스의 생성자를 Lombok으로 만들때 종종 사용했다.

- @Builder : 생성자에 Builder 패턴을 적용할 수 있도록 한다.

builder 패턴의 사용 예시

자주 사용하지는 않았지만, 참고할 만한 기능을 소개하자면 다음과 같다.

@Data : @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor을 한번에 적용하는 어노테이션이다. 단순하게 보면 편리해 보이지만, Setter가 생성될 뿐 아니라 ToString, EqualsAndHashCode 등에서 의도하지 않은 오류가 날 수 있다. 혹은, 추후 유지보수 도중 의도하지 않은 동작을 수행할 가능성이 생긴다.

@Setter : 필드변수들의 Setter 메서드를 자동으로 생성한다. 나는 Setter는 절대 존재하면 안된다는 주의이고, 대신 생성자를 통해 주입하여 그 객체의 값이 바뀌지 않는 불변 객체 주의를 선호한다. 그렇기에 이 어노테이션은 절대 사용하지 않고 있다. 설령 Setter가 급하게 필요하더라도, 어노테이션만 달아버리면 개방될 필요가 없는 다른 변수들에도 접근할 수 있어 분명 추후 문제가 생긴다.

@ToString : toString 메서드를 자동으로 생성해 준다. exclude 옵션을 통해 불필요한 필드변수는 빼고 연산할 수 있다.


더 자세한 내용은 이동욱님의 블로그(링크)를 참고하는 것 역시 추천한다.

 

2) 스프링부트로 웹 서비스 출시하기 - 2. SpringBoot & JPA로 간단 API 만들기

이번 시간엔 SpringBoot & JPA로 간단한 API를 만들 예정입니다. Tip) 아직 SI 환경에선 Spring & MyBatis 를 많이 사용하지만, 쿠팡/우아한형제들/NHN Entertainment 등 자사 서비스를 개발하는 곳에선 SpringBoo..

jojoldu.tistory.com

여기에서는 한가지 재미있는 내용을 소개하는데, 스프링 bean의 생성을 위해 어쩔 수 없이 만든 NoArgsConstructor가 잘못 쓰이지 않도록

옵션을 넣을 수 있다는 것이다.

@NoArgsConstructor(access = AccessLevel.PROTECTED)

이런 식으로!! 이 부분은 나도 조사해보면서 알았는데, 추후 프로젝트에 적용해 보려고 한다.


원래는 Lombok의 간단한 사용법과 고민에 대해 적어보려고 했는데, 내용이 길어졌다.

처음 스프링을 배울 때, Entity에는 빈 생성자가 필요하다, DTO를 쓸때도 빈 생성자를 만들어줘라 라는 이야기를 듣고 의심해보지 않았는데,

오늘 이 글을 쓰면서 스스로 의심하고 또 많은 내용을 찾아보게 되었다.

 

Lombok은 분명 코드의 길이를 획기적으로 줄이고 도메인 이해를 도울 수 있는 막강한 툴이다.

그러나 아무 생각 없이 사용한다면, 치명적인 결과를 낳을 수도 있는 툴이기도 하다.

그렇기에 Lombok을 사용하려고 한다면,

별 생각 없이 쓴 어노테이션 때문에 의도치 않은 동작이 생기지는 않을지,

유지보수 과정에서 문제가 생기지는 않을지 고민해보길 권한다.

 

잘못된 내용이 있다면 지적 부탁드립니다.

반응형

댓글