Spring аннотация @Value, не использующая значения по умолчанию, когда свойство отсутствует
Я пытаюсь использовать аннотацию @Value в параметрах конструктора следующим образом:
@Autowired
public StringEncryptor(
@Value("${encryptor.password:\"\"}") String password,
@Value("${encryptor.algorithm:\"PBEWithMD5AndTripleDES\"}") String algorithm,
@Value("${encryptor.poolSize:10}") Integer poolSize,
@Value("${encryptor.salt:\"\"}") String salt) {
...
}
Когда файл свойств присутствует в пути к классам, свойства загружаются отлично, и тест выполняется отлично. Однако, когда я удаляю файл свойств из пути к классам, я бы ожидал, что будут использоваться значения по умолчанию, например, poolSize будет установлен в 10 или алгоритм для PBEWithMD5AndTripleDES, но это не так.
Запуск кода через отладчик (который работал бы только после изменения @Value("${encryptor.poolSize:10}") Integer poolSize
до @Value("${encryptor.poolSize:10}") String poolSize
, поскольку он вызывал NumberFormatExceptions). Я обнаружил, что значения по умолчанию не заданы, а параметры находятся в форме:
poolSize = ${encryptor.poolSize:10}
или
algorithm = ${encryptor.algorithm:"PBEWithMD5AndTripleDES"}
а не ожидаемый
poolSize = 10
или
algorithm = "PBEWithMD5AndTripleDES"
На основе SPR-4785 должна работать надпись, такая как ${my.property:myDefaultValue}. Но это не для меня!
Спасибо
Ответы
Ответ 1
Возможно, инициализация конфигуратора заполнителя свойств завершилась неудачно из-за пропущенного файла свойств, так что заполнители не будут разрешены. Вы можете сконфигурировать его, чтобы игнорировать пропущенные файлы следующим образом (если вы используете пространство имен context
для его настройки):
<context:property-placeholder ignore-resource-not-found="true" ... />
Также вам не нужно "..."
по умолчанию.
Ответ 2
ignore-resource-not-found = "true" не требуется для выбора значений по умолчанию. Точка указания значения по умолчанию предназначена для его использования, если свойство не найдено нигде.
Я думаю, что последнее предложение в предыдущем ответе указывает на проблему - неправильный EL, который вы должны были первоначально предоставить, но затем удалить из примера. Тот факт, что вы получали исключения для преобразования формата, указывает на это. Обычно Spring автоматически преобразует строки в соответствующий "стандартный" Java-тип, и если вы предоставите собственную реализацию службы преобразования Spring для своих пользовательских объектов - пока ваша служба преобразования определена в контекст приложения.
"ignore-resource-not-found" полезен, когда вы вводите свойства через XML без параметров по умолчанию и не хотите, чтобы контейнер генерировал исключение, создающее экземпляр bean, если свойство не найдено. В таких случаях свойства bean будут инициализированы стандартными значениями Java, например. nulls для объектов, 0s для примитивных числовых значений и т.д.
Ответ 3
В моем случае разрешение значений свойств (и значений по умолчанию) не работало в тесте, где я использую конфигурацию на основе аннотации. Оказалось, что мне пришлось добавить PropertySourcesPlaceholderConfigurer
, чтобы свойства действительно разрешались. Это объяснялось в PropertySource Annotation JavaDoc:
Чтобы разрешить ${...} заполнители в определениях или аннотации @Value с использованием свойств из PropertySource, необходимо зарегистрировать PropertySourcesPlaceholderConfigurer. Это происходит автоматически при использовании в XML, но должно быть явно зарегистрировано с использованием статического метода @ Bean при использовании классов @Configuration. См. Раздел "Работа с внешними значениями" в разделе @Configuration Javadoc и "примечание о методах BeanFactoryPostProcessor-return @Bean" @Bean Javadoc для получения более подробной информации и примеров.
Следующий трюк:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
И если вы хотите добавить отдельные свойства:
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
Properties properties = new Properties();
properties.put("batchSize", "250");
propertySourcesPlaceholderConfigurer.setProperties(properties);
return propertySourcesPlaceholderConfigurer;
}