浅谈Spring和SpringBoot中的数据绑定(一)

在使用SpringBoot开发中经常使用配置文件来定义应用需要的数据项,例如数据字典,开始使用properties,然后使用XML,现在常使用YML

使用Properties格式没有层次,XML格式解析麻烦,编写复杂,YML简洁有层次应用快捷。于是在开发中使用YML定义如下数据项

data:
  dict:
    contentStatus:
      published: 已发布
      unpublished: 未发布
      trash: 回收站
    contentType:
      article: 文章
      activity: 活动
      page: 页面

 方法一:可使用SpringBoot提供的注解来载入上面的数据,实现代码如下:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;


@Component
@PropertySource(value = {"classpath:datadict.yml"}, factory = YmlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "data")
public class DataDictHolder {

    Map<String, Map<String, String>> dict = new HashMap<>();

    public Map<String, Map<String, String>> getDict() {
        return dict;
    }

    public void setDict(Map<String, Map<String, String>> dict) {
        this.dict = dict;
    }

    public String text(String type, String key) {
        Map<String, String> dictEntryMap = dict.get(type);
        if (MapUtil.isEmpty(dictEntryMap)) {
            return "";
        }
        String value = dictEntryMap.get(key);
        return value == null ? "" : value;
    }
}

使用注意:

1、@ConfigurationProperties(prefix = "data")

注解@ConfiguratinProperties指定的前缀与YML中的相应层次数据是否为当前类配置参数相对应,这里是第一层

2、配置类中定义的属性名

配置类中定义的属性名与前缀层次下的对应数据层次名称相一致,这里是第二层,名称为dict,相应的属性名也是dict,该类型是Map<String, Map<String, String>>

3、自定义YmlPropertySourceFactory

因为Spring中的注解PropertySource默认只能读取properties格式文件,如果想读出YML格式的文件,就需要自定义读取方式,好在可以使用PropertySource中的factory属性定义,自定义的YmlPropertySourceFactory代码实现如下:

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (resource == null) {
            return super.createPropertySource(name, resource);
        }
        Resource resourceResource = resource.getResource();
        if (!resourceResource.exists()) {
            return new PropertiesPropertySource(null, new Properties());
        } else if (resourceResource.getFilename().endsWith(".yml") ||
                resourceResource.getFilename().endsWith(".yaml")) {

            List<PropertySource<?>> sources =
                    new YamlPropertySourceLoader().load(resourceResource.getFilename(), resourceResource);
            return sources.get(0);
        }
        return super.createPropertySource(name, resource);
    }
}

 

posted @ 2022-02-16 22:57  培轩  阅读(191)  评论(0)    收藏  举报