Spring Boot инициализирует новый экземпляр для привязки вложенной конфигурации, когда в application.properties нет соответствующих вложенных пар ключ / значение - PullRequest
0 голосов
/ 14 января 2019

У меня есть класс конфигурации, как показано ниже. Все поля во внутреннем классе 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, когда к нему обращаются, используя его метод получения. Поскольку весенняя загрузка не не инициализирует его экземпляр, если не найдено ключей свойств с префиксом myconf.service.* в моем файле application.properties.

Вопрос:

Как сделать поле service для инициализации новым экземпляром вместе с указанными значениями поля по умолчанию, если в файле свойств нет соответствующих префиксных ключей?

Я не могу представить значение для аннотации @Value("${service:?????}") для поля service. Ничего не работает, пробовал, @Value("${service:}") или @Value("${service:new")

Ответы [ 2 ]

0 голосов
/ 17 января 2019

На основании @ M. Совет Deinum , сделал некоторые изменения в классе конфигурации. Я новичок в Spring, и, похоже, я неправильно понял, как Spring работает за кулисами.

  1. Сначала я удалил всю аннотацию @Value из внутреннего класса (т. Е. OptionalServiceConfigs), а также поле service в классе MyConfigs.
  2. Затем инициализировали все внутренние поля класса со встроенными значениями по умолчанию.
  3. В конструкторе MyConfigs я инициализировал новый экземпляр OptionalServiceConfigs для поля service.

Таким образом, всякий раз, когда в моем application.properties связанных ключах нет service, создается новый экземпляр со значениями по умолчанию.

Когда есть / есть service связанные ключи / с, Spring переопределяет мои значения по умолчанию на указанные значения в application.properties только полях, которые я указал.

Я полагаю, что с точки зрения Spring нет способа заранее узнать, что поле ссылки (т. Е. Поле service) будет связано с конфигурациями, если в файле конфигурации нет ни одного из его ключей. Это должно быть причиной, по которой Spring не инициализирует ее. Достаточно справедливо.

Полное решение:

@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
}
0 голосов
/ 14 января 2019

Вы можете попробовать такую ​​структуру, которая работает для меня вполне нормально:

@Data
@Validated
@ConfigurationProperties(prefix = "gateway.auth")
@Configuration
public class AuthProperties {

@NotNull
private URL apiUrl;

@Valid
@NotNull
private Authentication authentication;

@Data
public static class Authentication {
    @NotNull
    private Duration accessTokenTtl;
    @NotNull
    private String accessTokenUri;
    @NotNull
    private String clientId;
    @NotNull
    private String clientSecret;
    @NotNull
    private String username;
    @NotNull
    private String password;
    @Min(0)
    @NonNull
    private Integer retries = 0;
   }
}

Важно иметь геттеры и сеттеры, чтобы включить Spring для последующей обработки ConfigurationProperties, для этого я использую Lombok (@Data).

пожалуйста, смотрите здесь для более подробной информации:

Учебное пособие по настройке Baeldung

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...