Spring了解YAML中的属性

tol*_*ius 9 java spring yaml

Spring是否放弃使用YAML作为.properties/.xml的替代品,因为:

[春天开发者]:... YAML被认为是,但我们认为计算空白显着是制作中的支持噩梦... [来自春季论坛的参考]

我很自信YAML对于属性很有意义,我目前正在使用它,但是很难将属性注入到

<property name="productName" value="${client.product.name}" />
Run Code Online (Sandbox Code Playgroud)

时尚.

我缺少什么,或者我应该创建一个自定义的YamlPropertyPlaceholderConfigurer?

Bos*_*one 9

我不知道这有点太晚但不是 - 你不必实现整个YamlPropertyPlaceholderConfigurer而只需创建自定义PropertiesPersister并将其添加为可选参数.

这是您的配置的外观

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>file:///C:/somewhere/site.yaml</value>
    </property>
    <property name="propertiesPersister" ref="persister"></property>
</bean>
<bean id="persister" class="com.foo.utils.YamlPropertiesPersister"></bean>
Run Code Online (Sandbox Code Playgroud)

这里是使用SnakeYaml的裸骨(只读)实现,随意添加您需要的内容,包括错误处理

public class YamlPropertiesPersister implements PropertiesPersister {
@Override
public void load(Properties props, InputStream is) throws IOException {
    load(props, new InputStreamReader(is));
}

/**
 * We want to traverse map representing Yaml object and each time we find String=String pair we want to
 * save it as Property. As we are going deeper into map we generate compound key as path-like String
 * 
 * @param props
 * @param reader
 * @throws IOException
 * @see org.springframework.util.PropertiesPersister#load(java.util.Properties, java.io.Reader)
 */
@Override
public void load(Properties props, Reader reader) throws IOException {
    Yaml yaml = CollectorUtils.instanceOfYaml();
    Map<String, Object> map = (Map<String, Object>) yaml.load(reader);
    // now we can populate supplied props
    assignProperties(props, map, null);
}

/**
 * @param props
 * @param map
 */
public void assignProperties(Properties props, Map<String, Object> map, String path) {
    for (Entry<String, Object> entry : map.entrySet()) {
        String key = entry.getKey();
        if (StringUtils.isNotEmpty(path))
            key = path + "." + key;
        Object val = entry.getValue();
        if (val instanceof String) {
            // see if we need to create a compound key
            props.put(key, val);
        } else if (val instanceof Map) {
            assignProperties(props, (Map<String, Object>) val, key);
        }
    }
}

@Override
public void store(Properties props, OutputStream os, String header) throws IOException {
    throw new NotImplementedException("Current implementation is a read-only");
}

@Override
public void store(Properties props, Writer writer, String header) throws IOException {
    throw new NotImplementedException("Current implementation is a read-only");
}

@Override
public void loadFromXml(Properties props, InputStream is) throws IOException {
    throw new NotImplementedException("Use DefaultPropertiesPersister if you want to read/write XML");
}

@Override
public void storeToXml(Properties props, OutputStream os, String header) throws IOException {
    throw new NotImplementedException("Use DefaultPropertiesPersister if you want to load/store to XML");
}

@Override
public void storeToXml(Properties props, OutputStream os, String header, String encoding) throws IOException {
    throw new NotImplementedException("Use DefaultPropertiesPersister if you want to read/write XML");
}
}
Run Code Online (Sandbox Code Playgroud)

作为额外的好处 - 这是我如何创建Yaml实例

    public static Yaml instanceOfYaml() {
    DumperOptions options = new DumperOptions();
    options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
    options.setDefaultScalarStyle(ScalarStyle.DOUBLE_QUOTED);
    final Yaml yaml = new Yaml(new Loader(), new Dumper(options), new Resolver() {
        /**
         * @see org.yaml.snakeyaml.resolver.Resolver#addImplicitResolvers()
         */
        @Override
        protected void addImplicitResolvers() {
            addImplicitResolver(Tag.BOOL, BOOL, "yYnNtTfFoO");
            // disable resolving of floats and integers
            // addImplicitResolver(Tags.FLOAT, FLOAT, "-+0123456789.");
            // addImplicitResolver(Tag.INT, INT, "-+0123456789");
            addImplicitResolver(Tag.MERGE, MERGE, "<");
            addImplicitResolver(Tag.NULL, NULL, "~nN\0");
            addImplicitResolver(Tag.NULL, EMPTY, null);
            addImplicitResolver(Tag.TIMESTAMP, TIMESTAMP, "0123456789");
            addImplicitResolver(Tag.VALUE, VALUE, "=");
        }
    });
    return yaml;
}
Run Code Online (Sandbox Code Playgroud)

您也可以在我的博客中阅读此内容