Spring Boot:如何读取application.yml指定属性并忽略其余属性
在测试场景中,需要从application.yml读取部分属性进行验证,但Spring Boot会尝试处理所有属性,导致像{cipher}格式的属性抛出异常,希望忽略不需要的属性(如示例中的first.property)。
示例配置
first: property: {cipher}value # Spring尝试处理cipher时会抛出异常 second: property: value
配置类(简化为String类型)
@Configuration public class Configuration { @Bean @ConfigurationProperties(prefix = "second.property") public String secondProperty() { return new String(); } }
测试类
@SpringBootTest public class ConfigPropertiesCheckerIntegrationTest { @Autowired String secondProperty; @Test void checkAutoConfigEndpointProperties() { assertThat(secondProperty, is(notNullValue())); } }
核心疑问:如何让Spring忽略first.property并跳过对它的处理?
方法1:直接在测试中指定属性值
在测试类上添加@TestPropertySource,直接注入需要的属性值,完全绕过原配置文件中不需要的部分:
@SpringBootTest @TestPropertySource(properties = {"second.property=value"}) public class ConfigPropertiesCheckerIntegrationTest { // 测试代码保持不变 }
这种方式适合快速给测试场景指定固定值,无需依赖原配置文件内容。
方法2:环境加载阶段过滤属性
实现EnvironmentPostProcessor接口,在Spring加载环境时移除不需要的属性:
public class IgnorePropertiesPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { MutablePropertySources propertySources = environment.getPropertySources(); // 遍历所有属性源,移除前缀为first.property的属性 propertySources.stream() .filter(ps -> ps instanceof EnumerablePropertySource) .map(ps -> (EnumerablePropertySource<?>) ps) .forEach(ps -> { Arrays.stream(ps.getPropertyNames()) .filter(name -> name.startsWith("first.property")) .forEach(ps::removeProperty); }); } }
然后在src/test/resources/META-INF/spring.factories中注册该处理器:
org.springframework.boot.env.EnvironmentPostProcessor=com.yourpackage.IgnorePropertiesPostProcessor
该方法能在环境初始化阶段就过滤掉目标属性,避免Spring后续处理引发异常。
方法3:限定配置属性扫描范围
如果属性是通过@ConfigurationProperties绑定的,可通过@ConfigurationPropertiesScan指定仅扫描目标配置类,避免Spring处理其他无关属性的绑定逻辑:
@SpringBootTest @ConfigurationPropertiesScan(basePackageClasses = Configuration.class) public class ConfigPropertiesCheckerIntegrationTest { // 测试代码保持不变 }
注意:此方法仅对@ConfigurationProperties注解绑定的属性生效,若涉及其他自动配置类加载的属性,需结合其他方案。
方法4:禁用特定属性处理器
若异常是由特定属性处理器(如加密属性处理器)引发,可在测试中禁用对应的自动配置类:
@SpringBootTest(exclude = {EncryptionAutoConfiguration.class}) public class ConfigPropertiesCheckerIntegrationTest { // 测试代码保持不变 }
需将EncryptionAutoConfiguration.class替换为实际处理{cipher}格式属性的自动配置类。
内容的提问来源于stack exchange,提问作者евгений кунцевич

