여러 프로젝트를 진행하면서 사용한 롬복 라이브러리.
DTO나 Entity 코드를 작성할때 당연시하게
@Getter @Setter @Builder @NoArgsConstructor @AllArgsConstructor
위 다섯개를 사용해왔다. (Service, Controller에는 @RequiredArgsConstructor...)
하지만 여러 어노테이션이 정확히 어떤 기능 제공하고, 어떤 부작용이 있는지 깊이 이해하지 못하고 사용을 했던 감이 있다.
그래서 Lombok의 주요 어노테이션 기능과 주의사항을 정리한다.
@Getter
public class MemberDto {
private String age;
@Setter
private String name;
}
getter메서드의 기본 작동 방식 중 메서드 이름은get<필드명>인데,boolean타입은is<필드명>형식이다.- 필요한 경우메만 setter를 선택적으로 사용하고, getter와 setter를 남용하지 않는 것이 권장된다고 한다.
-setter사용 지양: 객체의 캡슐화 원칙이 깨질 수 있다. 불변객체를 설계하거나 데이터 무결성이 중요한 경우는 setter 사용을 최소화하는 것이 좋다.
toString을 적용하고 싶지 않다면@ToString.Exclude 추가 하거나,@ToString(exclude = "필드명") 옵션 사용@ToString(exclude = "age")
public class MemberDto {
private String age; // 제외됨
private String name;
@ToString.Exclude
private String address; // 제외됨
// public MemberDto() {} // 자동 생성
}
@ToString.Exclude를 사용하여 순환 참조를 방지@ToString 대신 수동으로 toString() 메서드를 작성공부를 하면서 사용한적이 있었지만, 진행했던 프로젝트에서는 사용한적이 없었다. -> 디버깅이나 로깅 시 객체 상태를 출력하는데 신경을 더 쓰지 못해서 그런것 같다.
@NoArgsConstructor
public class MemberDto {
private String age;
private String name;
// public MemberDto() {} // 자동 생성
}
@AllArgsConstructor
public class MemberDto {
private String age;
private String name;
// 자동 생성
/* public MemberDto(String age, String name) {
this.age = age;
this.name = name;
}
*/
final 키워드가 붙은 필드와 @NonNull 어노테이션이 붙은 필드를 포함하는 생성자를 자동으로 생성@RestController
@RequiredArgsConstructor
@RequestMapping("/api/study-posts")
public class StudyPostController {
private final StudyPostService studyPostService;
// 사용 시 생성
/* public StudyPostController(StudyPostService studyPostService) {
this.studyPostService = studyPostService
}
*/
final 필드만 포함되므로 필드 값이 변경되지 않음
equals(), hashCode() 메서드를 자동으로 생성@Getter
@Setter
@ToString
@RequiredArgsConstructor
@EqualsAndHashCode(of = {"title"}) // title 필드만 비교
public class StudyPostDto {
@NonNull
private String title;
private String description;
private String subject;
private String difficulty;
}
@Slf4j
public class Test() {
StudyPost studyPost1 = new StudyPost("java");
StudyPost studyPost2 = new StudyPost("java");
StudyPost studyPost3 = new StudyPost("springboot");
log.debug(studyPost1.equals(studyPost2)); // true
log.debug(studyPost1.equals(studyPost3)); // false
}
public class Test() {
StudyPost studyPost = StudyPost.builder()
.title("docker study")
.difficulty("high")
.build();
}
@AllArgsConstructor와 차이@AllArgsConstructor는 모든 필드를 포함하는 생성자를 생성하므로 객체 생성 시 모든 필드 값을 제공해야 한다.@Builder는 특정 필드만 설정하거나, 선택적으로 값을 초기화할 수 있다.// @AllArgsConstructor 사용
StudyPost studyPost1 = new StudyPost("Docker Study", "Advanced course", "High");
// @Builder 사용
StudyPost studyPost2 = StudyPost.builder()
.title("Docker Study")
.difficulty("High")
.build();
id 같은 필드는 객체 생성 시 초기화할 필요가 없음createdAt, UpdatedAt 같은 필드도 일반적으로 각각 어노테이션에서 자동 관리되므로, 객체 생성 시 수동으로 값을 전달할 필요가 없음public class StudyPost {
private Long id; // 자동 생성
private String title;
private String description;
private String difficulty;
private LocalDateTime createdAt; // @CreatedDate 어노테이션 관리
private LocalDateTime updatedAt; // @LastModifiedDate 어노테이션 관리
@Builder
public StudyPost(String title, String description) {
this.title = title;
this.description = description;
}
}
위와 같이 필요한 필드만 초기화 하도록 생성자를 지정한 후, 해당 생성자에 @Builder를 적용하는 것이 바람직하다.
@Getter @Setter @ToString @RequiredArgsConstructor @EqualsAndHashCode 어노테이션의 집합체@Data에 포함된 @ToString 은 객체의 모든 필드를 출력하는 toString() 메서드를 생성한다.@Data
public class User {
private Team team;
}
@Data
public class Team {
private User user;
}
// toString() 호출 시 User → Team → User → ... 무한 순환 발생
@ToString 설명과 같이 @ToString.Exclude를 사용해 특정 필드를 toString()에서 제외하거나, @Data 대신 필요한 어노테이션만 선택적으로 사용intellij를 사용하는 경우 Lombok 플러그인 설치 후
Settings > Build, Execution, Deployment > Compiler > Annotation Processors로 이동
Enable annotation processing 옵션을 체크해야 사용 가능하다.