레코드란?
- 불변(immutable) 데이터 객체를 쉽게 생성할 수 있도록 하는 새로운 유형의 클래스
- JDK14에서 preview로 등장하여 JDK16에서 정식 스펙으로 포함
비교
기존의 불변 데이터 객체
public class Person {
private final String name;
private final int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
- 상태(name, age)를 보유하는 불변 객체를 생성하기 위한 많은 코드를 작성함
- 모든 필드에 final을 사용하여 명시적으로 정의
- 필드 값을 모두 포함한 생성자
- 모든 필드에 대한 접근자 메서드(getter)
- 상속을 방지하기 위해 클래스 자체를 final로 선언하기도 함
- 로깅 출력을 제공하기 위한 toString 재정의
- 두 개의 인스턴스를 비교하기 위한 hashCode, equals 재정의
레코드를 이용한 불변 객체
public record Person(String name, int age){}
- 레코드 클래스를 사용하면 훨씬 간결한 방식으로 동일한 불변 데이터 객체 정의할 수 있음
- 이름(Person), 헤더(String name, int age), 바디({})
- 컴파일러는 헤더를 통해 내부 필드를 추론
- 생성자를 작성하지 않아도 되고 toString, equals, hashCode 메소드에 대한 구현을 자동으로 제공
public record BoardPrincipal(
String username,
String password,
Collection<? extends GrantedAuthority> authorities,
String email,
String nickname,
String memo
) implements UserDetails{
public static BoardPrincipal of(String username, String password, String email, String nickname, String memo) {
Set<RoleType> roleTypes = Set.of(RoleType.USER);
return new BoardPrincipal(
username,
password,
roleTypes.stream()
.map(RoleType::getName)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toUnmodifiableSet()),
email,
nickname,
memo
);
}
public static BoardPrincipal from(UserAccountDto dto){
return BoardPrincipal.of(
dto.userId(),
dto.userPassword(),
dto.email(),
dto.nickname(),
dto.memo()
);
}
public UserAccountDto toDto(){
return UserAccountDto.of(
username,
password,
email,
nickname,
memo
);
}
@Override public String getUsername() { return username; }
@Override public String getPassword() { return password; }
@Override public Collection<? extends GrantedAuthority> getAuthorities() { return authorities; }
@Override public boolean isAccountNonExpired() { return true; }
@Override public boolean isAccountNonLocked() { return true; }
@Override public boolean isCredentialsNonExpired() { return true; }
@Override public boolean isEnabled() { return true; }
public enum RoleType{
USER("ROLE_USER");
@Getter private final String name;
RoleType(String name) { this.name = name; }
}
}