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

error

产生该问题的原因:

ConfigurationClassParser.processPropertySource() 方法的try-catch块中,它的确存在捕获 FileNotFoundException 的意图。

无法捕获的位置


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

嵌套异常链处-原因


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

norun 异常被丢出外部方法


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

ResolutionMethod

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

Comment From: sbrannen

  • duplicate of #22276