Spring - 使用Value注释从本地配置文件中读取

问题描述 投票:1回答:1

我试图在Spring中使用Value注释从本地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的同一个包中,但配置文件不在resources文件夹中,因为这是一个服务层。所以它恰好在domain包下)。

当我尝试在我的第一个类中测试我的getConfigValue方法时,我得到NPE(我假设它是因为我作为getConfigValue方法的参数传入的configurationReader为null):

@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);
    } 

我不确定我的类实际上是否正在从配置文件中读取配置值。任何帮助将不胜感激!

附:代码已更新

java spring spring-boot configuration nullpointerexception
1个回答
2
投票

@值

Spring的@Value注释提供了一种将属性值注入组件的便捷方法,而不是提供属性文件路径

@PropertySource使用@PropertySource用于Doc

注释提供了一种方便的声明机制,用于将PropertySource添加到Spring的环境中。与@Configuration课程一起使用

给定包含键/值对testbean.name=myTestBean的文件app.properties,以下@Configuration类使用@PropertySource将app.properties贡献给Environment的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 Shortcomings

无法使用@PropertySource批注加载YAML文件。因此,如果您需要以这种方式加载值,则需要使用属性文件。

来测试用例你不应该创建新的DefaultEmailValidator实例你需要使用@SpringBootTest

@SpringBootTest Example

当我们需要引导整个容器时,可以使用@SpringBootTest注释。注释通过创建将在我们的测试中使用的ApplicationContext来工作。

RunWith(SpringRunner.class)

@RunWith(SpringRunner.class)用于提供Spring Boot测试功能和JUnit之间的桥梁。每当我们在JUnit测试中使用任何Spring Boot测试功能时,都需要这个注释。

@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);
} 
© www.soinside.com 2019 - 2024. All rights reserved.