출처 - [Lombok] 올바른 Lombok 사용법 - @Builder (tistory.com)
우리가 Spring에서 자주 볼 수 있는 Lombok들에 대해 알아보겠습니다
아래와 같은 코드가 있다고 할 때 이를 어떻게 리펙토링 할 수 있을까요?
@Getter
@Setter // 문제 1. 객체가 무분별하게 변경될 가능성 있음
@NoArgsConstructor // 문제 2. 기본 생성자의 접근 제어자가 불명확함
@Builder
@AllArgsConstructor // 문제3. 객체 내부의 인스턴스멤버들을 모두 가지고 있는 생성자를 생성 (매우 위험)
@Entity
public class Member
해결 1. @Setter를 사용하지 않기
Setter는 그 의도가 분명하지 않고 객체를 언제든지 변경할 수 있는 상태가 되어서 객체의 안전성이 보장받기 힘듭니다. 특히 엔티티에서는 @Setter를 사용 시 해당 업데이트 문이 어디서 누구에 의해 발생했는지 추적하기가 힘들어진다.
때문에 값 변경이 필요한 경우 의미 있는 메서드를 생성하여 이를 사용하는 것이 좋습니다.
해결 2.@NoArgsConstructor(access = AccessLevel.PROTECTED)로 변경
기본 생성자(NoArgsConstructor)의 접근 제어를 PROCTECTED 로 설정하면 아무런 값도 갖지 않는 의미 없는 객체의 생성을 막게 됩니다. 즉 무분별한 객체 생성에 대해 한번 더 체크할 수 있습니다.
//@NoArgsConstructor(access = AccessLevel.PROTECTED)
Member member = new Member(); //컴파일 에러 발생
이때, '의미있는 객체' 생성을 위해서@Builder을 사용할 수 있습니다.
@Builder를 사용하는 방법은 총 2가지인데,
- 클래스에@Builder를 붙이기
- 생성자에@Builder를 붙이기
해결 3. @AllArgsConstructor 는 쓰지 않기
만약 해결 2의 방법1을 사용, 클래스 레벨에서@Builder와 @NoArgsConstructor를 함께 쓰면 오류가 발생합니다.
이를 해결하기 위해서는 모든 필드를 가지는 생성자를 만들어주어야 하는데
이때 @AllArgsConstructor를 사용하는 것은 추천하지 않습니다. 이는 @AllArgsConstructor 가 너무 위험하기 때문입니다, @AllArgsConstructor는 클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성하는데, 인스턴스 멤버의 선언 순서에 영향을 받기 때문에 두 변수의 순서를 바꾸면 생성자의 입력 값 순서도 바뀌게 되어 검출되지 않는 치명적인 오류를 발생시킬 수 있습니다.
리펙토링 결과
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Member {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private String picture;
@Enumerated(EnumType.STRING)
private Role role;
public Member update(String name, String picture) {
this.name = name;
this.picture = picture;
return this;
}
// 생성자에 @Builder 적용
@Builder
public Member(String name, String email, String picture, Role role) {
this.name = name;
this.email = email;
this.picture = picture;
this.role = role;
}
}
참고
만렙 개발자 키우기
개발 경험치를 쌓아가며 성장하는 개발자의 기록 일지입니다.
www.nowwatersblog.com
자주 사용되는 lombok, 주의 사항 | devk0ng's blog
@Getter, @Setter : 말그대로 getter, setter method를 생성해주는 놈이야! AccessLevel을 명시해줌으로써 접근제한자를 지정 해 줄 수 있어. 123456789public Class Sample { @Getter private String attr1; @Getter(AccessLevel.PRIVATE)
devk0ng.github.io
[Lombok] @Builder와 @NoArgsConstructor 동시 사용시 주의사항
@Builder와 @NoArgsConstructor를 함께 사용하려면, @AllArgsConstructor도 함께 사용하거나 모든 필드를 가지는 생성자를 직접 만들어 줘야 한다. 또한, @Builder를 사용할 때 @NoArgsConstructor뿐만 아니라..
precioustar.tistory.com
'programming study > B-Spring' 카테고리의 다른 글
filter, interceptor, aop (0) | 2023.04.16 |
---|---|
@Async (0) | 2023.04.12 |
[Spring]RestTemplate과 HttpEntity (제네릭과ParameterizedTypeReference) (0) | 2023.01.02 |
프로퍼티 파일(yml) 여러개 설정하기 (0) | 2022.12.30 |
spring에서 session 사용하기 (0) | 2022.12.23 |