불변성을 위한 @ConstructingBinding이 필요 없다고 한다.

작성일 : 2022년 09월 11일
  • #Spring Boot

새 프로젝트를 진행하며 설정 값 적용을 위해 Properties 클래스를 작성 중 이전 프로젝트와 마찬가지로 @ConstructorBinding 어노테이션을 적용 했는데 오류가 발생했다. 똑같은 방식으로 적용했는데도 한 곳에서만 오류가 발생하는 걸 보아 버전 차이로 발생하는 오류로 생각되어 업데이트 기록을 확인해 보았다. 참고로 이전 프로젝트는 2.7.0 버전, 새 프로젝트는 3.0.0-SNAPSHOP 버전이다.

업데이트 기록

Github Spring Boot 프로젝트를 참고하여 버전 기록을 둘러보던 중 찾은 내용이다.

@ConstructingBinding No Longer Needed at the Type Level


@ConstructorBinding is no longer needed at the type level on @ConfigurationProperties classes and should be removed. When a class or record has multiple constructors, it may still be used on a constructor to indicate which one should be used for property binding.

Improved @ConstructorBinding Detection

When using constructor bound @ConfigurationProperties the @ConstructorBinding annotation is no longer required if the class has a single parameterized constructor. If you have more than one constructor, you’ll still need to use @ConstructorBinding to tell Spring Boot which one to use.


For most users, this updated logic will allow for simpler @ConfigurationProperties classes. If, however, you have a @ConfigurationProperties and you want to inject beans into the constructor rather than binding it, you’ll now need to add an @Autowired annotation.

간단히 정리하자면 클래스의 생성자가 여러 개일 경우를 제외하면 더이상 @ConstructorBinding 어노테이션을 사용할 필요가 없다는 내용이다.

Type Level

추가적으로 @ConstructingBinding No Longer Needed at the Type Level 이 부분에서 Type Level이 무엇인지 잘 모르겠어서 검색해보니 다음과 같은 내용을 찾을 수 있었다.

  1. Type Level은 Java Language Specification에 나오는 공식 사양은 아니다.

  2. 메서드 수준에서 적용되는 어노테이션이 아니다.

  3. Class, interface, enum, record 수준에서 적용된다.

  4. 어노테이션 선언 부의 @Target 어노테이션에서 확인 할 수 있다.

확인

위 내용을 토대로 확인 해본 결과 정말 다음과 같이 Type Level에서의 적용을 삭제했다는 걸 확인 할 수 있었다.

//Spring Boot 2.7.0
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR }) //해당 부분
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConstructorBinding {

}

//Spring Boot 3.0.0
@Target(ElementType.CONSTRUCTOR) // 해당 부분
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConstructorBinding {

}

결론

Spring Boot 3.0.0 이후 버전에서는 Type Level에 적용된 @ConstructBinding 어노테이션을 제거하자.

참고 자료

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0.0-M2-Release-Notes

https://stackoverflow.com/questions/73096757/what-is-type-level-annotation?noredirect=1&lq=1