class PropertiesYaml extends Properties {
    static final String SOLON_ENV = "solon.env";
    static final String SOLON_ENV_ON = "solon.env.on";
    static final String YML_PART_SPLIT = "---";

    AtomicReference<String> envRef = new AtomicReference<>(System.getProperty(SOLON_ENV));


    private Yaml createYaml() {
        return new Yaml();
    }

    public void loadYml(InputStream inputStream) throws Exception {<FILL_FUNCTION_BODY>}

    public void loadYml(Reader reader) throws IOException {
        //支持多部分切割
        List<String> partList = splitParts(reader);

        //开始加载多部分属性

        String partStr = null;
        for (int i = 0; i < partList.size(); i++) {
            partStr = partList.get(i);
            if (Utils.isBlank(partStr)) {
                continue;
            }
            final int fi = i;
            this.loadYml(partStr, partProp -> {
                //2.同步环境变量
                if (envRef.get() == null && fi == 0 && partProp.containsKey(SOLON_ENV)) {
                    envRef.set(String.valueOf(partProp.get(SOLON_ENV)));
                }
            });
        }
    }

    public void loadYml(String str) {
        this.loadYml(str, null);
    }

    public void loadYml(String str, Consumer<Map<Object, Object>> c) {
        //1.加载部分属性
        Object tmp = createYaml().load(str);
        Map<Object, Object> partProp = new TreeMap<>();
        load0(partProp, "", tmp);

        if (partProp.size() == 0) {
            return;
        }

        if (c != null) {
            //2.其他操作，如同步环境变量
            c.accept(partProp);
        }

        //3.根据条件过滤加载
        if (partProp.containsKey(SOLON_ENV_ON)) {
            //如果有环境条件，尝试匹配 //支持多环境匹配。例：solon.env.on: pro1 | pro2
            String envOn = String.valueOf(partProp.get(SOLON_ENV_ON));
            if (Arrays.stream(envOn.split("\\|")).anyMatch(e -> e.trim().equals(envRef.get()))) {
                super.putAll(partProp);
            }
        } else {
            super.putAll(partProp);
        }
    }

    /**
     * 切割多部分
     */
    private List<String> splitParts(Reader reader) throws IOException {
        List<String> partList = new ArrayList<>();
        //支持多部分切割
        try (BufferedReader in = new BufferedReader(reader)) {
            StringBuffer buffer = new StringBuffer();
            String line = null;
            while ((line = in.readLine()) != null) {
                if (line.startsWith(YML_PART_SPLIT)) { //用 starts 替代 pattern 提高性能
                    partList.add(buffer.toString());
                    buffer.setLength(0);
                } else {
                    buffer.append(line).append("\n");
                }
            }
            partList.add(buffer.toString());
        }

        return partList;
    }

    private void load0(Map<Object, Object> temProp, String prefix, Object tmp) {
        if (tmp instanceof Map) {
            ((Map<String, Object>) tmp).forEach((k, v) -> {
                String prefix2 = prefix + "." + k;
                load0(temProp, prefix2, v);
            });
            return;
        }

        if (tmp instanceof List) {
            //do_put(prefix, tmp);
            int index = 0;
            for (Object v : ((List) tmp)) {
                String prefix2 = prefix + "[" + index + "]";
                load0(temProp, prefix2, v);
                index++;
            }
            return;
        }

        if (tmp == null) {
            put0(temProp, prefix, "");
        } else {
            put0(temProp, prefix, String.valueOf(tmp));
        }
    }

    private void put0(Map<Object, Object> temProp, String key, Object val) {
        if (key.startsWith(".")) {
            temProp.put(key.substring(1), val);
        } else {
            temProp.put(key, val);
        }
    }
}

        try (InputStreamReader is = new InputStreamReader(inputStream)) {
            this.loadYml(is);
        }
    
<methods>public void <init>() ,public void <init>(int) ,public void <init>(java.util.Properties) ,public synchronized void clear() ,public synchronized java.lang.Object clone() ,public synchronized java.lang.Object compute(java.lang.Object, BiFunction<? super java.lang.Object,? super java.lang.Object,?>) ,public synchronized java.lang.Object computeIfAbsent(java.lang.Object, Function<? super java.lang.Object,?>) ,public synchronized java.lang.Object computeIfPresent(java.lang.Object, BiFunction<? super java.lang.Object,? super java.lang.Object,?>) ,public boolean contains(java.lang.Object) ,public boolean containsKey(java.lang.Object) ,public boolean containsValue(java.lang.Object) ,public Enumeration<java.lang.Object> elements() ,public Set<Entry<java.lang.Object,java.lang.Object>> entrySet() ,public synchronized boolean equals(java.lang.Object) ,public synchronized void forEach(BiConsumer<? super java.lang.Object,? super java.lang.Object>) ,public java.lang.Object get(java.lang.Object) ,public java.lang.Object getOrDefault(java.lang.Object, java.lang.Object) ,public java.lang.String getProperty(java.lang.String) ,public java.lang.String getProperty(java.lang.String, java.lang.String) ,public synchronized int hashCode() ,public boolean isEmpty() ,public Set<java.lang.Object> keySet() ,public Enumeration<java.lang.Object> keys() ,public void list(java.io.PrintStream) ,public void list(java.io.PrintWriter) ,public synchronized void load(java.io.Reader) throws java.io.IOException,public synchronized void load(java.io.InputStream) throws java.io.IOException,public synchronized void loadFromXML(java.io.InputStream) throws java.io.IOException, java.util.InvalidPropertiesFormatException,public synchronized java.lang.Object merge(java.lang.Object, java.lang.Object, BiFunction<? super java.lang.Object,? super java.lang.Object,?>) ,public Enumeration<?> propertyNames() ,public synchronized java.lang.Object put(java.lang.Object, java.lang.Object) ,public synchronized void putAll(Map<?,?>) ,public synchronized java.lang.Object putIfAbsent(java.lang.Object, java.lang.Object) ,public synchronized java.lang.Object remove(java.lang.Object) ,public synchronized boolean remove(java.lang.Object, java.lang.Object) ,public synchronized java.lang.Object replace(java.lang.Object, java.lang.Object) ,public synchronized boolean replace(java.lang.Object, java.lang.Object, java.lang.Object) ,public synchronized void replaceAll(BiFunction<? super java.lang.Object,? super java.lang.Object,?>) ,public void save(java.io.OutputStream, java.lang.String) ,public synchronized java.lang.Object setProperty(java.lang.String, java.lang.String) ,public int size() ,public void store(java.io.Writer, java.lang.String) throws java.io.IOException,public void store(java.io.OutputStream, java.lang.String) throws java.io.IOException,public void storeToXML(java.io.OutputStream, java.lang.String) throws java.io.IOException,public void storeToXML(java.io.OutputStream, java.lang.String, java.lang.String) throws java.io.IOException,public void storeToXML(java.io.OutputStream, java.lang.String, java.nio.charset.Charset) throws java.io.IOException,public Set<java.lang.String> stringPropertyNames() ,public synchronized java.lang.String toString() ,public Collection<java.lang.Object> values() <variables>private static final jdk.internal.misc.Unsafe UNSAFE,protected volatile java.util.Properties defaults,private volatile transient ConcurrentHashMap<java.lang.Object,java.lang.Object> map,private static final long serialVersionUID