[英]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 contributeapp.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
进入测试案例,您不应该创建需要使用@SpringBootTest
的DefaultEmailValidator
新实例。
@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.