java - Spring - 使用值注释从本地配置文件中读取
问题描述
我正在尝试使用 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
但配置文件不在资源文件夹中,因为这是一个服务层。所以它就在domain
包装下面)。
当我尝试在第一堂课中测试我的 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);
}
我不确定我的班级此时是否真的从配置文件中读取配置值。任何帮助将不胜感激!
PS 代码更新了
解决方案
@价值
Spring 的@Value 注解提供了一种方便的方式将属性值注入到组件中,而不是提供属性文件路径
@PropertySource对该文档使用@PropertySource
注释提供了一种方便的声明机制,用于将 PropertySource 添加到 Spring 的环境中。
@Configuration
与类一起使用给定一个包含键/值对的文件 app.properties
testbean.name=myTestBean
,以下@Configuration
类使用@PropertySourc
e 为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;
}
}
无法使用
@PropertySource
注解加载 YAML 文件。因此,如果您需要以这种方式加载值,则需要使用属性文件。
来到测试用例,您不应该创建DefaultEmailValidator
需要使用的新实例@SpringBootTest
@SpringBootTest 示例
当
@SpringBootTest
我们需要引导整个容器时,可以使用注解。注释通过创建将在我们的测试中使用的 ApplicationContext 来工作。
RunWith(SpringRunner.class)
@RunWith(SpringRunner.class) 用于在 Spring Boot 测试功能和 JUnit 之间架起一座桥梁。每当我们在 JUnit 测试中使用任何 Spring Boot 测试功能时,都需要此注解。
@MockBean
这里另一个有趣的事情是@MockBean 的使用。它创建了一个 Mock
电子邮件验证器测试
@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);
}
推荐阅读
- reactjs - 如何使用 react 访问 axios
- node.js - Angular 通用 npm run serve:ssr 抛出错误:package.json 不存在
- java - Gradle、SpringBoot、MavenPublish - 发布仅包含依赖项和/或约束,没有版本
- java - 如何使用java在android studio应用程序中由多个注册用户访问Firebase Firestore集合?
- openmdao - 在 openMDAO 中,消除非活动约束有多重要?
- linux - Ubuntu 18.04 / 20.04 的预置文件挂在格式化磁盘屏幕上
- apache-flink - Flink 任务管理器中的 slot 是什么?
- typescript - 3路多对多typeOrm
- android - 强制 NFC 调度事件 // 禁用和重新启用 NFC 系统功能
- c# - EF Core 代码优先:种子数据但忽略约束