#spring #spring-boot #configuration
#весна #весна-загрузка #конфигурация
Вопрос:
У меня есть эта конкретная проблема с моим файлом конфигурации yml. У меня есть многомодульный проект maven следующим образом:
app
|-- core
|-- web
|-- app
У меня есть этот файл конфигурации в core
проекте
@Configuration
@PropertySource("core-properties.yml")
public class CoreConfig {
}
И это отображение:
@Component
@ConfigurationProperties(prefix = "some.key.providers.by")
@Getter
@Setter
public class ProvidersByMarket {
private Map<String, List<String>> market;
}
Вот мои core-properties.yml
some.key.providers:
p1: 'NAME1'
p2: 'NAME2'
some.key.providers.by.market:
de:
- ${some.key.providers.p1}
- ${some.key.providers.p2}
gb:
- ${some.key.providers.p1}
Например, когда я загружаю файл через активацию профиля, переименуйте файл в application-core-properties.yml
, и тогда -Dspring.profiles.active=core-properties
это сработает, однако, если при попытке загрузить файл через @PropertySource("core-properties.yml")
это не получается, и я получаю следующую ошибку:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-03-27 10:07:36.397 -ERROR 13474|| --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'some.key.providers.by.market' to java.util.Map<java.lang.String, java.util.List<java.lang.String>>:
Reason: No converter found capable of converting from type [java.lang.String] to type [java.util.Map<java.lang.String, java.util.List<java.lang.String>>]
Action:
Update your application's configuration
Process finished with exit code 1
Комментарии:
1. Вы не можете загружать файлы YAML с помощью
@PropertySource
(см. mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files ). Используйте механизмы загрузки spring по умолчанию для загрузки дополнительных конфигурационных файлов вместо@PropertySource
.
Ответ №1:
Возможно, у вас нет эквивалентной структуры свойств, например
spring:
profiles: test
name: test-YAML
environment: test
servers:
- www.abc.test.com
- www.xyz.test.com
---
spring:
profiles: prod
name: prod-YAML
environment: production
servers:
- www.abc.com
- www.xyz.com
И класс конфигурации должен быть
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class YAMLConfig {
private String name;
private String environment;
private List<String> servers = new ArrayList<>();
// standard getters and setters
Ответ №2:
Я решил проблему, реализовав следующее, PropertySourceFactory
подробно описанное в here
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
} catch (IllegalStateException e) {
// for ignoreResourceNotFound
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException)
throw (FileNotFoundException) e.getCause();
throw e;
}
}
}
Ответ №3:
У меня была похожая проблема, и я нашел обходной путь, подобный этому:
diacritic:
isEnabled: true
chars: -> I wanted this to be parsed to map but it didn't work
ą: a
ł: l
ę: e
И мое решение до сих пор:
diacritic:
isEnabled: true
chars[ą]: a -> these ones could be parsed to Map<String, String>
chars[ł]: l
chars[ę]: e