spring-framework
spring-framework copied to clipboard
YamlPropertySourceLoader causes "@PropertySource(ignoreResourceNotFound = true)" invalid
Affects version: 5.3.22
该问题造成的影响:
尊敬的团队,当我使用 @PropertySource 注解通过 YamlPropertySourceLoader 加载时,即使 ignoreResourceNotFound 属性为 true,仍然会因无法找到文件抛出 FileNotFoundException 异常,导致项目无法启动。
Configuration code
@Configuration
@PropertySource(value = {"classpath:command.yml", "file:config/custom-command.yml"},
factory = YamlPropertySourceFactory.class,
encoding = "UTF-8",
ignoreResourceNotFound = true)
public class CommandConfig {
}
PropertySourceFactory code
public class YamlPropertySourceFactory implements PropertySourceFactory {
@NotNull
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).get(0);
}
}
Error

产生该问题的原因:
在 ConfigurationClassParser.processPropertySource() 方法的try-catch块中,它的确存在捕获 FileNotFoundException 的意图。

但是,在 new YamlPropertySourceLoader().load() 执行过程中,如果产生了异常则会调用 handleProcessError 方法。此方法对异常链进行了包装,使原本的 FileNotFoundException 变为 IllegalStateException 。

从而导致抛出的 IllegalStateException 异常在外部catch块无法被捕获,导致 ignoreResourceNotFound 无法被执行,异常被抛出。

tips:catch语句只会判断主异常是否符合要求,不会也不应该检查cause。

临时解决方案
目前我将其抛出的 IllegalStateException 进行拆包并重新丢出,项目可以正常工作,但这显然并不优雅。

我曾有进行修复的想法,但我并不了解 ResolutionMethod 的作用,且我的机器运行spring-framework这个庞大的项目较为吃力。
或许可以从下图展示处开始思考。可能是状态判断的逻辑编写错误导致原本应该进行 logger.warn() 却进行了 throw IllegalStateException ?
定位到此处:org.springframework.beans.factory.config.YamlProcessor 第218行,在 5.3.x 分支。
org.springframework.beans.factory.config.YamlProcessor line 218 for branch 5.3.x

非常抱歉我没有使用English进行描述的能力。 这并不是一个严重的问题,至少目前可以run。