열심히 만들어보다가 왜 생성자를 사용하고 final 키워드를 사용해도 되는지 궁금하여 조사해보았다. 아래 코드는 이를 적용한 내용이다.
@Component
@RequiredArgsConstructor
public class Admin implements ApplicationRunner{
private final AdminRepository adminRepository;
private final PasswordEncoder passwordEncoder;
@Override
public void run(ApplicationArguments args) throws Exception {
Optional<AdminEntity> optionalAdminEntity = Optional.ofNullable(adminRepository.findByUsernameIs("admin"));
optionalAdminEntity.orElseGet(() -> adminRepository.save(
AdminEntity.builder()
.username("admin")
.password(passwordEncoder.encode("root123!@#"))
.build()));
}
@Scheduled(fixedRate = 3600000)
public void updatePassword(){
Optional<AdminEntity> optionalAdminEntity = Optional.ofNullable(adminRepository.findByUsernameIs("admin"));
optionalAdminEntity.ifPresent(
adminEntity -> {
adminEntity.updatePassword(passwordEncoder.encode("root123!@#"));
adminRepository.save(adminEntity);
});
}
}
##
먼저 조사해보니 생성자가 필요한 이유를 찾아보니 "클래스를 초기화하는 동안 필요한 정보를 저장하고 전달"하는 것이라고 한다.
여기서 잘 생각해보면 초기화가 중요해보였는데 다른 객체와 클래스에서 변화가 주어진다면 그 변화를 새로 받아야하기 때문에 초기화 하는게 합리적이라는 생각을 할 수 있게 되었고 외부에서 의존성을 주입 받을때, 초기화를 해주는게 필수적이란 것을 알게 되었다.
final 키워드
클래스의 부모 생성자가 실행되기 이전에 초기화를 진행하고 불변성이
@NoArgsConstructor(access = PROTECTED)
@Entity
@Getter
@DynamicUpdate
@DynamicInsert
@NoArgsConstructor(access = PROTECTED)
public class AdminEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(name = "adminId")
private String username;
private String password;
@Builder
public AdminEntity(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public void updatePassword(String newPassword) {
this.password = newPassword;
}
}
가장 간단한 이유는 기본생성자의 무분별한 생성을 막아 "의도하지 않은" 엔티티의 생성을 방지할 수 있게 된다는 점이고
@Builder를 통해 의미있는 객체만 생성할 수 있다.