Spring - Использование аннотации Value для чтения из локального файла конфигурации - PullRequest
1 голос
/ 22 апреля 2019

Я пытаюсь использовать аннотацию Value в Spring для чтения из локального файла application.yaml, который я поместил в тот же пакет, что и мой основной класс и класс модульного тестирования. У меня есть простой класс с методом, который получает значение конфигурации:

public class EmailValidator {

    String getConfigValue(configurationProvider1 configurationReader, String configName) {
        String value = null;
        ConfigurationProvider reader;
        try {
            reader = configurationReader.configurationProvider();
            value = reader.getProperty(configName, String.class);
            //the `reader` above is null when I run the test, so I get Null Pointer Exception on this line
            if (value == null) {
                LOGGER.warn("The configuration for " + configName + " cannot be found.");
            }
        } catch (Exception e){
            e.printStackTrace();
        }

        return value;
    }
} 

И у меня есть класс провайдера конфигурации, который устанавливает считыватель конфигурации так, чтобы мой класс выше мог использовать его для чтения файла application.yaml:

@Configuration
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor
@ComponentScan
public class configurationProvider1 {

        @Value("${configFilesPath:./domain/application.properties}")//Not really sure if this is the right way of locating my configuration file
        @Getter
        private String filePath;

        @Bean
        public ConfigurationProvider configurationProvider() throws FileNotFoundException {
            if (!Paths.get(this.filePath).toFile().exists()) {
                throw new FileNotFoundException("Configuration file doesn't exist: " + this.filePath);
            }

            ConfigFilesProvider configFilesProvider =
                    () -> Collections.singletonList(Paths.get(filePath).toAbsolutePath());
            ConfigurationSource source = new FilesConfigurationSource(configFilesProvider);
            Environment environment = new ImmutableEnvironment(this.filePath);

            return new ConfigurationProviderBuilder()
                    .withConfigurationSource(source)
                    .withEnvironment(environment)
                    .build();
        }
    } 

Как указано выше, я не уверен, является ли @Value("${configFilesPath:./domain/application.properties}") правильным способом поиска моего локального файла application.properties (классы находятся в том же пакете с именем domain, но файл конфигурации не находится в папке ресурсов поскольку это служебный уровень, то есть он находится прямо под пакетом domain.

И когда я пытаюсь протестировать свой метод getConfigValue в моем первом классе, я получаю NPE (я предполагаю, что это потому, что configReader, который я передаю в качестве параметра методу getConfigValue, равен нулю):

@RunWith(SpringRunner.class)
@SpringBootTest
public class EmailValidatorTest {

    @MockBean
    private configurationProvider1 configurationReader = mock(configurationProvider1.class);

    @Autowired
    private DefaultEmailValidator validator;//maybe I should inject the dependency somewhere?

    @Test
    public void simple(){
        String a = validator.getConfigValue(configurationReader,"mail.subject.max.length");
        System.out.println(a);
    } 

Я не уверен, что мой класс действительно читает значение конфигурации из файла конфигурации в данный момент. Любая помощь будет принята с благодарностью!

P.S. Код обновлен

1 Ответ

2 голосов
/ 22 апреля 2019

@ Value

Аннотация Spring @Value предоставляет удобный способ вставки значений свойств в компоненты, а не для указания пути к файлу свойств

@ PropertySource Для этого используйте @ PropertySource Документ

Аннотация, обеспечивающая удобный и декларативный механизм добавления PropertySource в среду Spring,Для использования вместе с @Configuration классами

. При наличии файла app.properties, содержащего пару ключ / значение testbean.name=myTestBean, следующий класс @Configuration использует @PropertySourc e, чтобы внести app.properties вНабор PropertySources среды.

Пример

 @Configuration
 @PropertySource("classpath:/com/myco/app.properties")
 public class AppConfig {

 @Autowired
 Environment env;

 @Bean
 public TestBean testBean() {
     TestBean testBean = new TestBean();
     testBean.setName(env.getProperty("testbean.name"));
     return testBean;
   }
 }

24.7.4 Недостатки YAML

Файлы YAML не могут быть загружены с помощью аннотации @PropertySource.Таким образом, в случае, если вам нужно загрузить значения таким образом, вам нужно использовать файл свойств.

Переход к тестовому примеру вам не следуетсоздайте новый экземпляр DefaultEmailValidator, вам нужно использовать @SpringBootTest

@ SpringBootTest Пример

Примечание @SpringBootTestиспользоваться, когда нам нужно загрузить весь контейнер.Аннотация работает путем создания ApplicationContext, который будет использоваться в наших тестах.

RunWith (SpringRunner.class)

@ RunWith (SpringRunner).class) используется для обеспечения моста между функциями тестирования Spring Boot и JUnit.Всякий раз, когда мы используем какие-либо функции тестирования Spring Boot в наших тестах JUnit, эта аннотация потребуется.

@ MockBean

Еще одна интересная вещь здесьэто использование @MockBean.Он создает макет

EmailValidatorTest

 @RunWith(SpringRunner.class)
 @SpringBootTest
 public class EmailValidatorTest {

@MockBean
private configurationProvider1 configurationReader;

@Autowire
private DefaultEmailValidator validator

@Test
public void testGetConfigValue(){
    String a = validator.getConfigValue(configurationReader,"mail.subject.max.length");
    System.out.println(a);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...