简体   繁体   English

Spring-使用值批注从本地配置文件读取

[英]Spring - Using Value annotation to read from the local config file

I am trying to use the Value annotation in Spring to read from the local application.yaml file I put in the same package as my main and unit test class. 我试图在Spring中使用Value批注从与主测试和单元测试类放在同一包中的本地application.yaml文件读取。 I have a simple class with the method that gets the config value: 我有一个简单的类,带有获取配置值的方法:

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

And I have a configuration provider class which sets the configuration reader so that my class above can make use of it to read the application.yaml file: 我有一个配置提供程序类,用于设置配置读取器,以便我上面的类可以利用它来读取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();
        }
    } 

As commented above, I'm not sure if @Value("${configFilesPath:./domain/application.properties}") is a right way of locating my local application.properties file (The classes are in the same package called domain but the config file is not in the resources folder since this is a service layer. So it is just right under the domain package). 如上所述,我不确定@Value("${configFilesPath:./domain/application.properties}")是否是查找本地application.properties文件的正确方法(这些类位于称为domain的同一程序包中但是配置文件不在资源文件夹中,因为它是服务层,因此位于domain包的正下方)。

And when I try to test my getConfigValue method in my first class, I get NPE (I assume its because the configurationReader I am passing in as a parameter to getConfigValue method is null): 当我尝试在第一个类中测试getConfigValue方法时,我得到了NPE(我认为是因为我作为参数传递给getConfigValue方法的configurationReader为空):

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

I am not sure if my class is actually reading the config value from the config file at this point. 我不确定目前我的班级是否真的从配置文件中读取配置值。 Any help would be greatly appreciated! 任何帮助将不胜感激!

PS The code is updated PS代码已更新

@Value @值

Spring's @Value annotation provides a convenient way to inject property values into components, not to provide the properties file path Spring的@Value注释提供了一种方便的方法来将属性值注入到组件中,而不是提供属性文件路径

@PropertySource Use @PropertySource for that Doc @PropertySource对该文档使用@PropertySource

Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. 注释提供了一种方便的声明性机制,用于将PropertySource添加到Spring的Environment中。 To be used in conjunction with @Configuration classes @Configuration类一起使用

Given a file app.properties containing the key/value pair testbean.name=myTestBean , the following @Configuration class uses @PropertySourc e to contribute app.properties to the Environment's set of PropertySources. 给定一个包含键/值对testbean.name=myTestBean的文件app.properties,以下@Configuration类使用@PropertySourc e将app.properties贡献给环境的PropertySources集合。

Example

 @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 24.7.4 YAML的缺点

YAML files cannot be loaded by using the @PropertySource annotation. 无法使用@PropertySource批注加载YAML文件。 So, in the case that you need to load values that way, you need to use a properties file. 因此,在需要以这种方式加载值的情况下, 需要使用属性文件。

Coming to Test case you should not create new instance of DefaultEmailValidator you need to use @SpringBootTest 进入测试案例,您不应该创建需要使用@SpringBootTestDefaultEmailValidator新实例。

@SpringBootTest Example @SpringBootTest 示例

The @SpringBootTest annotation can be used when we need to bootstrap the entire container. 当我们需要引导整个容器时,可以使用@SpringBootTest批注。 The annotation works by creating the ApplicationContext that will be utilized in our tests. 批注通过创建将在我们的测试中使用的ApplicationContext起作用。

RunWith(SpringRunner.class) RunWith(SpringRunner.class)

@RunWith(SpringRunner.class) is used to provide a bridge between Spring Boot test features and JUnit. @RunWith(SpringRunner.class)用于在Spring Boot测试功能和JUnit之间建立桥梁。 Whenever we are using any Spring Boot testing features in out JUnit tests, this annotation will be required. 每当我们在JUnit测试中使用任何Spring Boot测试功能时,都将需要此批注。

@MockBean @MockBean

Another interesting thing here is the use of @MockBean. 另一个有趣的事情是@MockBean的使用。 It creates a Mock 它创建了一个模拟

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用@Value注释从Spring Boot中的属性文件读取值 - Not able to read value from properties file in Spring Boot using @Value annotation Spring:使用@Value注释时,Bean无法从外部属性文件中读取值 - Spring: Bean fails to read off values from external Properties file when using @Value annotation 使用Spring配置文件中的条目作为注释属性的值 - Using an entry from the Spring configuration file as value for annotation property 运行测试类时,在 Spring Maven 项目中,使用 @Value 注释无法从 .properties 文件中正确读取属性 - When running test class, properties can't be read properly from .properties file by using @Value annotation, in Spring Maven project spring从属性文件传递值到注释 - spring pass value from property file to annotation 无法在 spring 启动时从配置中读取文件 - Cannot read file from config in spring boot 尝试从 yml 文件中读取 int 数组列表并使用 spring 注释 @Value List 加载<int[]></int[]> - Trying to read a List of int array from yml file and load with spring annotation @Value List<int[]> 无法使用 spring-cloud-config-server 从本地 git 存储库读取配置 - Unable to read configurations from local git repository using spring-cloud-config-server 是否可以使用 Spring 和 @Value 注释将 YAML 属性读入 Map - Is it possible to read YAML property into Map using Spring and @Value annotation 使用Spring注释读取属性文件中的选定内容 - Read a selected content in Property file using spring annotation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM