더 application.properties에서 중첩 된 키 / 값 쌍을 거기에 해당하는 경우 봄 부츠는 바인딩 중첩 된 구성을위한 새로운 인스턴스를 초기화하지

isuru89 :

나는 다음과 같은 구성 클래스가 있습니다. 내부 클래스 필드의 모든 OptionalServiceConfigs사용 주석으로 기본값 갖고 @Value아래에 도시한다.

가끔 내에서 application.properties파일, 그것은 하지 않는 한이 service앞에 둔 속성을. 이 경우, 우리는로드 한 할 OptionalServiceConfigs기본 필드 값으로 인스턴스를.

@Configuration
@ConfigurationProperties(prefix = "myconf")
public class MyConfigs {

   // ... rest of my configs

   @Value("${service:?????}") // what to put here, or can I?
   private OptionalServiceConfigs service;   // this is null

   // In this class all fields have a default value.
   public static class OptionalServiceConfigs {

       @Value("${mode:local}")
       private String mode;

       @Value("${timeout:30000}")
       private long timeout;

       // ... rest of getter and setters
   }

   // ... rest of getter and setters
}

그러나 불행하게도 service필드는 null이 자사의 getter 메소드를 사용하여 액세스 할 때. 봄 부팅이 때문에 하지 의 인스턴스를 초기화 접두사 발견 프로퍼티 키가 없을 때 myconf.service.*내에서 application.properties파일.

질문:

어떻게 할 수 service필드가 지정된 기본 필드 값과 함께 새로운 인스턴스를 초기화 특성 파일에 해당하는 접두사 키가없는 경우?

내가 주석에 넣어 값을 상상할 수 없다 @Value("${service:?????}")에 대한 service필드. 아무것도 작품, 시도, @Value("${service:}")또는@Value("${service:new")

isuru89 :

를 기반으로 @M. Deinum 의 조언, 구성 클래스의 일부를 변경했다. 나는 봄에 안돼서 그리고 내가 봄이 막후 어떻게 작동하는지 오해를 보인다.

  1. 우선 모두 제거 @Value내부 클래스 (예에서 주석 OptionalServiceConfigs), 그리고뿐만 아니라 service필드 MyConfigs클래스를.
  2. 그런 다음, 기본값 인라인 모든 내부 클래스 필드를 초기화.
  3. 의 생성자에서 MyConfigs, 나는의 새로운 인스턴스를 초기화 OptionalServiceConfigs필드에 대해 service.

이있을 때마다, 이렇게함으로써 service 내에서 관련 키 application.properties새로운 인스턴스가 이미 디폴트 값으로 작성되지 않았습니다.

있을 때 /있는 service관련 키 / S, 다음 봄에 지정된 값으로 내 디폴트 값을 대체하지 application.properties 에만 분야 (들) 내가 지정한.

나는 그것이 참조 필드 (즉 것을 미리 알 수있는 방법이 없다는 것을 봄의 관점에서 생각 service필드)의 키 중 어느 것도 구성 파일에 존재하지 않는 구성, 관련이있을 것이다. 즉 스프링이 초기화되지 않는 이유가 있어야합니다. 그럴 수 있지.

완벽한 솔루션 :

@Configuration
@ConfigurationProperties(prefix = "myconf")
public class MyConfigs {

   // ... rest of my configs

   private OptionalServiceConfigs service;

   public static class OptionalServiceConfigs {

       private String mode = "local";

       private long timeout = 30000L;

       // ... rest of getter and setters
   }

   public MyConfigs() {
      service = new OptionalServiceConfigs();
   }

   // ... rest of getter and setters
}

추천

출처http://43.154.161.224:23101/article/api/json?id=215397&siteId=1