SpringBootシリーズ@PropertySourceはYAMLファイルを読み込みます

SpringBootシリーズ@PropertySourceサポートYAMLファイルの読み込み

最近の実験では、@PropertySource注釈属性プロファイルを読みたい、マッピングされ、性質がテストに何の問題を使用していないに慣れている、時折置き換えYAMLファイルは、プロパティの値を読んでいない発見されました

PropertySourceは、我々はまた、@valueコメントに読み込むことができますを読んでYAMLデフォルトでサポートされていない@ YAML構文は非常に簡単ですので、設定ファイルを書くことを好むYAML、それは、明らかであるが、属性の束は、その後、一つ一つが非常に面倒です読んで情報と自分の実験を見つけるためにインターネットを介して、我々はサポートがYAMLのために達成できることを見出し

次に、なぜ@PropertySourceノートは、デフォルトでサポートされていませんか?あなたは、単にソースコード付きで見ることができます

@PropertySource出典:
ここに画像を挿入説明
コメントによると、クラスのロードにリソースファイルとしてデフォルトDefaultPropertySourceFactoryクラスを使用する
ここに画像を挿入説明
内部のか読み取ることがPropertiesLoaderUtilsツールの基礎となるSpringフレームワークを呼び出す
ここに画像を挿入説明
PropertiesLoaderUtils.loadPropertiesを
ここに画像を挿入説明
ソースからも見ることができるxmlファイルをサポートし、読者がそれをサポートすることができます読みますリーダーオブジェクトまたは一部を取得するのinputStream
ここに画像を挿入説明

ここに画像を挿入説明
load0方法は、ここで重要なのである、プラスゲンロック
ここに画像を挿入説明
アウト重要load0方法のクロールを:

private void load0 (LineReader lr) throws IOException {
        char[] convtBuf = new char[1024];
        int limit;
        // 当前key所在位置
        int keyLen;
        // 当前value所在位置
        int valueStart;
        char c;//读取的字符
        boolean hasSep;
        boolean precedingBackslash;//是否转义字符,eg:/n etc.
        // 一行一行地读取
        while ((limit = lr.readLine()) >= 0) {
            c = 0;
            keyLen = 0;
            valueStart = limit;
            hasSep = false;

            //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
            precedingBackslash = false;
            //key的长度小于总的字符长度,那么就进入循环
            while (keyLen < limit) {
                c = lr.lineBuf[keyLen];
                //need check if escaped.
                if ((c == '=' ||  c == ':') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    hasSep = true;
                    break;
                } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    break;
                }
                if (c == '\\') {
                    precedingBackslash = !precedingBackslash;
                } else {
                    precedingBackslash = false;
                }
                keyLen++;
            }
            //value的起始位置小于总的字符长度,那么就进入该循环
            while (valueStart < limit) {
                c = lr.lineBuf[valueStart];
                //当前字符是否非空格类字符
                if (c != ' ' && c != '\t' &&  c != '\f') {
                    if (!hasSep && (c == '=' ||  c == ':')) {
                        hasSep = true;
                    } else {
                        break;
                    }
                }
                valueStart++;
            }
            //读取key
            String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
            //读取value
            String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
            put(key, value);
        }
    }

OK、キーと値取得トラバーサルの一連の後、ベリファイ等、次いで結腸、等しい数の、空間によれば、これは行毎に読み出され、ソースから見ることができ、YAML文法は、インデントを同定することです自分のテストによって、この方法も読んでYAMLファイルをサポートしていない、ソースコードのプロパティが実装プロパティは、ブログを参照することができ、より具体的なソースは次のとおりです。https://www.cnblogs.com/liuming1992/p/4360310.html 、より詳細に、このブログを書きます

[OK]を、その後、コンフィギュレーション・ファイルYAMLの読み取りを実現するために例を与えます

# 测试ConfigurationProperties
user:
  userName: root
  isAdmin: true
  regTime: 2019/11/01
  isOnline: 1
  maps: {k1 : v1,k2: v2}
  lists:
   - list1
   - list2
  address:
    tel: 15899988899
    name: 上海市

YAMLはDefaultPropertySourceFactoryが読みファクトリクラスのリソースファイルを書き込む模倣します:

package com.example.springboot.properties.core.propertyResouceFactory;

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Properties;

/**
 * <pre>
 *  YAML配置文件读取工厂类
 * </pre>
 * <p>
 * <pre>
 * @author nicky.ma
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2019/11/13 15:44  修改内容:
 * </pre>
 */
public class YamlPropertyResourceFactory implements PropertySourceFactory {

    /**
     * Create a {@link PropertySource} that wraps the given resource.
     *
     * @param name     the name of the property source
     * @param encodedResource the resource (potentially encoded) to wrap
     * @return the new {@link PropertySource} (never {@code null})
     * @throws IOException if resource resolution failed
     */
    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource encodedResource) throws IOException {
        String resourceName = Optional.ofNullable(name).orElse(encodedResource.getResource().getFilename());
        if (resourceName.endsWith(".yml") || resourceName.endsWith(".yaml")) {//yaml资源文件
            List<PropertySource<?>> yamlSources = new YamlPropertySourceLoader().load(resourceName, encodedResource.getResource());
            return yamlSources.get(0);
        } else {//返回空的Properties
            return new PropertiesPropertySource(resourceName, new Properties());
        }
    }
}

豆クラスの属性マッピング、工場出荷時のパラメータの変化に注意を払うを書きます、factory = YamlPropertyResourceFactory.class

package com.example.springboot.properties.bean;

import com.example.springboot.properties.core.propertyResouceFactory.CommPropertyResourceFactory;
import com.example.springboot.properties.core.propertyResouceFactory.YamlPropertyResourceFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 *
 * </pre>
 *
 * @author nicky
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2019年11月03日  修改内容:
 * </pre>
 */
@Component
@PropertySource(value = "classpath:user.yml",encoding = "utf-8",factory = YamlPropertyResourceFactory.class)
@ConfigurationProperties(prefix = "user")
public class User {

    private String userName;
    private boolean isAdmin;
    private Date regTime;
    private Long isOnline;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Address address;

    @Override
    public String toString() {
        return "User{" +
                       "userName='" + userName + '\'' +
                       ", isAdmin=" + isAdmin +
                       ", regTime=" + regTime +
                       ", isOnline=" + isOnline +
                       ", maps=" + maps +
                       ", lists=" + lists +
                       ", address=" + address +
                       '}';
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public boolean isAdmin() {
        return isAdmin;
    }

    public void setAdmin(boolean admin) {
        isAdmin = admin;
    }

    public Date getRegTime() {
        return regTime;
    }

    public void setRegTime(Date regTime) {
        this.regTime = regTime;
    }

    public Long getIsOnline() {
        return isOnline;
    }

    public void setIsOnline(Long isOnline) {
        this.isOnline = isOnline;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

package com.example.springboot.properties.bean;

/**
 * <pre>
 *
 * </pre>
 *
 * @author nicky
 * <pre>
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2019年11月03日  修改内容:
 * </pre>
 */
public class Address {
    private String tel;
    private String name;

    @Override
    public String toString() {
        return "Address{" +
                       "tel='" + tel + '\'' +
                       ", name='" + name + '\'' +
                       '}';
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

JUnitテストクラスコード:

package com.example.springboot.properties;

import com.example.springboot.properties.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootPropertiesConfigApplicationTests {

    @Autowired
    User user;

    @Test
    public void testConfigurationProperties(){
        System.out.println(user);
    }


}
User{userName='root(15899988899)', isAdmin=false, regTime=Fri Nov 01 00:00:00 SGT 2019, isOnline=1, maps={k2=v2, k1=-30363940}, lists=[1f90e323-8a9c-4194-a31c-be9abbe9ce38, a869f68947faa92964d2a36ce86ee980], address=Address{tel='15899988899', name='上海浦东区'}}

私たちは、元のYAMLをサポートするだけでなく、プロパティをサポートしたい場合は、再起草propertyResourceFactoryクラスになります

package com.example.springboot.properties.core.propertyResouceFactory;

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

/**
 * <pre>
 *  通用的资源文件读取工厂类
 * </pre>
 * <p>
 * <pre>
 * @author mazq
 * 修改记录
 *    修改后版本:     修改人:  修改日期: 2019/11/25 10:35  修改内容:
 * </pre>
 */
public class CommPropertyResourceFactory implements PropertySourceFactory {

    /**
     * Create a {@link PropertySource} that wraps the given resource.
     *
     * @param name     the name of the property source
     * @param resource the resource (potentially encoded) to wrap
     * @return the new {@link PropertySource} (never {@code null})
     * @throws IOException if resource resolution failed
     */
    @Override
    public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
        String resourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
        if (resourceName.endsWith(".yml") || resourceName.endsWith(".yaml")) {
            List<PropertySource<?>> yamlSources = new YamlPropertySourceLoader().load(resourceName, resource.getResource());
            return yamlSources.get(0);
        } else {
            return new DefaultPropertySourceFactory().createPropertySource(name, resource);
        }
    }
}

呼び出されたときは、工場出荷時のパラメータは、それを変更するには

@PropertySource(value = "classpath:user.yml",encoding = "utf-8",factory = CommPropertyResourceFactory.class)

このクラスは、元のプロパティファイルをサポートすることができ、ファイルもYAMLをサポートすることができます

User{userName='root(15899988899)', isAdmin=false, regTime=Fri Nov 01 00:00:00 SGT 2019, isOnline=1, maps={k2=v2, k1=-30363940}, lists=[1f90e323-8a9c-4194-a31c-be9abbe9ce38, a869f68947faa92964d2a36ce86ee980], address=Address{tel='15899988899', name='上海浦东区'}}

ダウンロード:GitHubのダウンロードリンク

おすすめ

転載: www.cnblogs.com/mzq123/p/11936075.html