spring framework에서 특정 라이브러리 세팅을 라이브러리화 하기 위해서 wrapping을 하던 도중 일어난 일이다.

환경은 다음과 같다

목표

설정 파일은 다음과 같다.

https://github.com/pointware/client-test/blob/main/client/src/main/kotlin/com/example/clienttest/config/ClientProperties.kt

알게 된 점.

  1. 무지성으로 @EnableConfigurationProperties(ClientProperties::class) 를 적용해보았다.
    1. 알고보니 ClientProperties의 bean을 알아서 생성해준다.
      1. @ConfigurationProperties beans can be registered in the standard way라고 annotation comment에 적혀 있다.
    2. 결과적으로 properties를 생성할 때 환경에 따른 기본값 설정을 할 수 없다.
  2. 원하는 객체의 root에만 @ConfigurationProperties 가 달려 있으면 된다.
    1. 굳이 객체 안에 있는 다른 객체에도 필요한 것은 아니다.
  3. @ConfigurationProperties 가 달린 bean은 이런 순서로 생성된다.
    1. @Bean이 달린 method에서 생성 (beanFactory)

    2. ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization

    3. ConfigurationPropertiesBinder#bind

      1. 이것 때문에 properties 객체는 value로 생성하면 런타임에서 exception이 발생한다.

        아무래도 reflection으로 하는건 아닌거 같고 setter를 원한다.

      Failed to bind properties under 'message' to com.example.clienttest.config.ClientProperties:
      
          Property: message.interval
          Value: "99"
          Origin: class path resource [application.properties] - 12:18
          Reason: java.lang.IllegalStateException: No setter found for property: interval
      
      Action:
      
      Update your application's configuration
      

결론