Я использую Spring Boot 2.0 со стандартным файлом свойств application.yml. Я хотел бы разделить его на отдельные файлы свойств, потому что он становится огромным.
Также я хотел бы написать тесты для проверки правильности свойств: значений, которые будут представлены в контексте производственного приложения (а не в тестовом).
Вот мой файл с недвижимостью: SRC / основные / ресурсы / конфигурация / custom.yml
my-property:
value: 'test'
Класс недвижимости:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Data
@Configuration
@ConfigurationProperties(prefix = "my-property")
@PropertySource("classpath:config/custom.yml")
public class MyProperty {
private String value;
}
Контрольная работа:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyProperty.class)
@EnableConfigurationProperties
public class MyPropertyTest {
@Autowired
private MyProperty property;
@Test
public void test() {
assertEquals("test", property.getValue());
}
}
Но тест не проходит с ошибкой:
java.lang.AssertionError:
Expected :test
Actual :null
Также я вижу, что значение свойства - null при запуске приложения, распечатав его в ApplicationRunner.
.
Когда я использовал application.yml для всех свойств, все было хорошо с той же конфигурацией.
Как поставить правильную конфигурацию свойств и тесты, чтобы все заработало?
Ссылка на Репозиторий Github
Кроме того, такие случаи легче отлаживать, если вы можете создать очень простое минимальное приложение и предоставить ссылку на него с github.
Возможный дубликат Spring @PropertySource с использованием YAML
@Prashant вот: github.com/bullet-tooth/spring-custom-properties




@TestPropertySource может решить вашу проблему.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyProperty.class)
@TestPropertySource(locations = "classpath:test.properties")
public class MyPropertyTest {
@Autowired
private MyProperty property;
@Test
public void test() {
assertEquals("test", property.getValue());
}
}
Надеюсь, поможет.
Как упоминалось OP в принятом ответе, @TestPropertySource в настоящее время не работает с файлами yml.
Если это ваш точный код, это означает, что вы читаете свое свойство из неправильного файла свойств.
замените свой ресурс собственности на эту строку.
@PropertySource("classpath:config/services.yml")
Спасибо за Ваш ответ. Извините, я пропустил это и исправил в своем вопросе. Но это не помогает :(.
В общем, я нашел правильный способ иметь собственные свойства yaml в моем приложении.
Проблема в том, что Spring не поддерживает файлы yaml как @PropertySource (ссылка на выпуск). И вот обходной путь, как бороться с тем, что описано в весенняя документация.
Итак, чтобы иметь возможность загружать свойства из файлов yaml, вам необходимо:
* Для реализации EnvironmentPostProcessor
* Прописать в spring.factories
Пожалуйста, посетите этот репозиторий github для полного примера.
Также большое спасибо за вашу поддержку, ребята!
Я немного опоздал на вечеринку, но это тоже может помочь. Решение, представленное в качестве ответа, пока что является лучшим подходом, но вот альтернатива, которую я использовал
Используйте профили и измените bean-компонент PropertySoucesPlaceHolderConfiguration, чтобы загружать необходимые файлы свойств на основе профилей. Он загружает application.properties по умолчанию, но другие файлы свойств -oauth_DEV и oauth_QA загружаются на основе установленных профилей.
@Bean
public PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurerconfigurer() {
System.out.println("Inside Placeholder bean");
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
ClassPathResource cls1= new ClassPathResource("application.properties");
ClassPathResource cls2 = null;
Map<String, Object> propMap = ((ConfigurableEnvironment) ctx.getEnvironment()).getSystemProperties();
for(Map.Entry<String, Object> entrySet: propMap.entrySet()) {
System.out.println("Map.Key:"+entrySet.getKey()+" Map.valiue:"+entrySet.getValue());
}
List<String> profiles= Arrays.asList(ctx.getEnvironment().getActiveProfiles());
if (profiles == null || profiles.isEmpty()) {
if (!propMap.containsKey("spring.profiles.active")) {
cls2 = new ClassPathResource("oauth-default.properties");
} else {
cls2 = new ClassPathResource("oauth-"+propMap.get("spring.profiles.active")+".properties");
}
}else {
for(String profile:profiles) {
if (profile.equalsIgnoreCase("DEV")) {
cls2 = new ClassPathResource("oauth-DEV.properties");
}else if (profile.equalsIgnoreCase("QA")) {
cls2 = new ClassPathResource("oauth-QA.properties");
}else if (profile.equalsIgnoreCase("UAT")) {
cls2 = new ClassPathResource("oauth-UAT.properties");
}else if (profile.equalsIgnoreCase("PROD")){
cls2 = new ClassPathResource("oauth-PROD.properties");
}else {
cls2 = new ClassPathResource("oauth-default.properties");
}
}
}
cfg.setLocations(cls1,cls2);
//cfg.setPlaceholderPrefix("#{");
return cfg;
}
Затем создайте другой bean-компонент, который считывает свойства на основе префикса - «security.oauth2.client».
@Configuration
@ConfigurationProperties(prefix = "security.oauth2.client")
public class OauthSecurityConfigurationDto {
private String clientId;
private String clientSecret;
private String scope;
private String accessTokenUri;
private String userAuthorizationUri;
private String grantType;
private String resourceIds;
private String registeredRedirectUri;
private String preEstablishedRedirectUri;
private String useCurrentUri;
private String userInfoUri;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAccessTokenUri() {
return accessTokenUri;
}
public void setAccessTokenUri(String accessTokenUri) {
this.accessTokenUri = accessTokenUri;
}
public String getUserAuthorizationUri() {
return userAuthorizationUri;
}
public void setUserAuthorizationUri(String userAuthorizationUri) {
this.userAuthorizationUri = userAuthorizationUri;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
public String getResourceIds() {
return resourceIds;
}
public void setResourceIds(String resourceIds) {
this.resourceIds = resourceIds;
}
public String getRegisteredRedirectUri() {
return registeredRedirectUri;
}
public void setRegisteredRedirectUri(String registeredRedirectUri) {
this.registeredRedirectUri = registeredRedirectUri;
}
public String getPreEstablishedRedirectUri() {
return preEstablishedRedirectUri;
}
public void setPreEstablishedRedirectUri(String preEstablishedRedirectUri) {
this.preEstablishedRedirectUri = preEstablishedRedirectUri;
}
public String getUseCurrentUri() {
return useCurrentUri;
}
public void setUseCurrentUri(String useCurrentUri) {
this.useCurrentUri = useCurrentUri;
}
public String getUserInfoUri() {
return userInfoUri;
}
public void setUserInfoUri(String userInfoUri) {
this.userInfoUri = userInfoUri;
}
}
Помните, что сеттеры важны, потому что ConfigurationProperties загружает значения в свойства класса только тогда, когда определены геттеры и сеттеры.
Теперь мы можем автоматически подключать зависимость везде, где это необходимо, и использовать свойство.
Вы пытались использовать аннотацию
@TestPropertySourceдля определения местоположения ваших файлов конфигурации?