前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次SpringBoot2.x的@ImportResource和@PropertySource的前言中不允许有内容的坑

记一次SpringBoot2.x的@ImportResource和@PropertySource的前言中不允许有内容的坑

作者头像
RRT冻羊
发布2022-11-03 13:11:25
4470
发布2022-11-03 13:11:25
举报
文章被收录于专栏:冻羊技术思考冻羊技术思考

记一次SpringBoot2.x的@ImportResource和@PropertySource的坑

        众所周知,SpringBoot提倡的是无配置文件,也就摒弃了以前用Spring时繁重的.xml配置文件,取而代之的使用SpringBoot特有的@Configuration注解的JavaConfig配置类。配置方式和XML配置方式几乎一一对应,少有区别。
        那么当我们需要在SpringBoot中,需要使用XML配置文件,或者需要使用额外的.properties, .yml文件时,我们需要怎么做?
这时候就想到了几种方式:@ImportResource, @PropertySource
@ImportResource 是用于导入外部的.xml文件
@PropertySource 是用于导入变量类型的配置文件如.properties .yml
如果你用@ImportResource(locations = “xxx.yml”),通常情况你会得到这样的报错,

Caused by: org.xml.sax.SAXParseExcepton; lineNumber: 1; columnNumber: 1; 前言中不允许有内容          网上有大量关于这种错误的说法,但是绝大部分都是说你的文件编码格式有问题,需要转换。我在试过大量的方法后,还是不行,同时我也看到很多解决帖的下方留言,大多数都是留言不行,解决不了,我高度怀疑那些没质量的解决帖都是互相抄袭的。但是有一种方法我没有试,就是用notePad方式打开文件,然后保存为 UTF-8 with no BOM 的方式

         在尝试了很多次之后,我都无法通过@ImportResource的方式来导入外部.yml .properties配置文件,我也没有细心去查阅相关的源码,因此我转而关注@PropertySource来帮助我解决问题。

在使用@PropertySource的时候又发现了一个问题,它能正常帮助我导入.properties文件,我也能通过@ConfigurationProperties和@Value来得到配置文件中的相应变量值,但是它不能正确解读.yml文件。我想对于SpringBoot的常年开发者来说,早就已经把习惯改为用YML语言来书写配置文件,要换回使用properties虽然不麻烦,也有转换工具帮助,但是就不能有一种方法解决这个问题吗?

可喜可贺的是,@PropertySource里面有一个属性叫factory,默认实现类是DefaultPropertySourceFactory,这个factory的作用是解析配置文件,因此简单翻阅了DefaultPropertySourceFactory的源码,发现它对yml的支持非常鸡肋,默认是只能解析.properties文件。因此我对其做了扩展,让其在解析配置文件的时候,判断配置文件是.properties还是.yml,然后走相应的解析逻辑。
代码语言:javascript
复制
/**
 * 该类是扩展{@link org.springframework.core.io.support.DefaultPropertySourceFactory}的,
 * 用于{@link org.springframework.context.annotation.PropertySource}的factory属性。
 *
 * @PropertySource的facotroy属性,默认是使用 DefaultPropertySourceFactory 实现。该实现只能解析.properties配置文件,
 * 因此.yml文件无法解析。
 *
 */
public class YmlPropertiesFactory extends DefaultPropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource)
            throws IOException {
        String sourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
        if (!resource.getResource().exists()) {
            // return an empty Properties
            return new PropertiesPropertySource(sourceName, new Properties());
        } else if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
            Properties propertiesFromYaml = loadYaml(resource);
            return new PropertiesPropertySource(sourceName, propertiesFromYaml);
        } else {
            return super.createPropertySource(name, resource);
        }
    }

    /**
     * load yaml file to properties
     *
     * @param resource
     * @return
     * @throws IOException
     */
    private Properties loadYaml(EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}
代码语言:javascript
复制
@PropertySource(value = {"classpath:dy.yml"}, ignoreResourceNotFound = true, factory = YmlPropertiesFactory.class)
好了,现在你就能正常解析YML文件
小结:

(1) 如果你要导入外部XML文件,用@ImportResource (2) 如果你要导入的是.properties .yml这样的配置文件,用@PropertySource

或许我的总结是错误的,但就目前来看,这样能够解决SpringBoot导入外部配置文件时的问题,或许ImportResource也能导入.properties .yml文件,只是我方式用错了,如果有深入研究的过的朋友,可以在下方留言为社区贡献一份力量。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 记一次SpringBoot2.x的@ImportResource和@PropertySource的坑
    •         众所周知,SpringBoot提倡的是无配置文件,也就摒弃了以前用Spring时繁重的.xml配置文件,取而代之的使用SpringBoot特有的@Configuration注解的JavaConfig配置类。配置方式和XML配置方式几乎一一对应,少有区别。
      •         那么当我们需要在SpringBoot中,需要使用XML配置文件,或者需要使用额外的.properties, .yml文件时,我们需要怎么做?
        • 这时候就想到了几种方式:@ImportResource, @PropertySource
          • @ImportResource 是用于导入外部的.xml文件
            • @PropertySource 是用于导入变量类型的配置文件如.properties .yml
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档