@PropertySource指定文件地址
@ConfigurationProperties指定前缀。

第一次:

SpringBoot 读取配置文件
demo如下:
designers.yml文件

designer:
  owner:
    openids:
      - 8hV+lc6uYmfnXlfrVh52j0wBH6QOrs7Cyo/WM3SaHLA=
      - 3g+vDhtKqRHf97zKoJ8K0eSnv6hX4dLcNHXvDKxdb28=
      - 3e0EHRNifV73VxAjq6269j98NupXr8yjEgpUfiGb+g8=
      - kEPoIITwJePavbYUAsM/uPRJioi/ueApxPFulw6s/eM=
    usernames:
      - liming
      - xiaohong
      - zam
      - zqm

config配置:

/**
 * 配置表
 *
 * @date:2018/12/12
 * @author zqm
 */
@ConfigurationProperties(prefix = "designer")
@Component
public class DesignProperties {
    private Map<String, List<String>> owner;

    public Map<String, List<String>> getOwner() {
        return owner;
    }

    public void setOwner(Map<String, List<String>> owner) {
        this.owner = owner;
    }
}

测试demo:

@RequestMapping("/test")
 public String test() {
        Map<String, List<String>> map = designProperties.getOwner();
        List<String> ids= map.getOrDefault("openids", Arrays.asList("fail"));
        return JSON.toJSONString(ids);
    }

结果狠狠的打了一把脸!竟然是500!,NPE.

map是个空问题出在配置文件类上,咋回事呢?然后打断点到配置文件,发现启动初始化的时候根本没有进来,擦,问题出在读取文件上,文件读取不成功,特意百度了一下,没写错啊,我看别人是properties文件,这个注解PropertySource还难道不支持yml,搞什么✈️啊,进了源码看下,看到有个默认factory,

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.io.support.PropertySourceFactory;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {

	/**
	 * Indicate the name of this property source. If omitted, a name will
	 */
	String name() default "";

	/**
	 * Indicate the resource location(s) of the properties file to be loaded. 指定资源地址
	 */
	String[] value();

	/**
	 * Indicate if failure to find the a {@link #value() property resource} should be
	 * ignored.
	 * <p>{@code true} is appropriate if the properties file is completely optional.
	 * Default is {@code false}.
	 * @since 4.0
	 */
	boolean ignoreResourceNotFound() default false;

	/**
	 * A specific character encoding for the given resources, e.g. "UTF-8".
	 * @since 4.3
	 */
	String encoding() default "";

	/**
	 * Specify a custom {@link PropertySourceFactory}, if any.
	 * <p>By default, a default factory for standard resource files will be used.
	 * @since 4.3
	 * @see org.springframework.core.io.support.DefaultPropertySourceFactory
	 * @see org.springframework.core.io.support.ResourcePropertySource
	 */
	Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;

}

因此:我看了下PropertySourceFactory只有一个默认的实现

而这个PropertySourceFactory工厂只处理properties配置文件,既然这样得自己定义实现一个YamFactory了。

springboot获取自定义yml的值 springboot读取自定义yml配置文件_List

第二次:

修改后的配置文件:

/**
 * 配置表
 *
 * @author zqm
 * @date:2018/12/12
 */
@PropertySource(value = "classpath:designers.yml", factory = yamFactory.class)
@ConfigurationProperties(prefix = "designer")
@Component
@Data
public class DesignProperties {
    private Map<String, List<String>> owner;
}

yml工厂类:

package com.zqm.config;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

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

/**
 * @describe:
 * @author:zqm
 */
public class YamFactory 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();
    }
}

结果:读取了配置文件内容,哈哈哈哈!爽

springboot获取自定义yml的值 springboot读取自定义yml配置文件_spring_02

总结:

@ConfigurationProperties有的版本里面有
location属性可以直接指定文件地址,貌似后面没有了。
@PropertySource 的factory属性默认解析的propertie文件。
因此读取yml文件需要自定义工厂。
学习一个注解类是,还是要多多看看源码显示其各个属性含义,看不懂也得去百度啊。靠着之前的经验会一脸懵逼,有些注解版本更新还蛮大的。

附录1基本类型的配置文件格式:

aalist:
  #对应字符串
  name: zha
  #对用list
  myList:
    - a
    - b
  #对应数组
  arrays: 1,2,3
  #对应map
  valueMap:
    name: zqm
    age: 20
    sex: male
  #对应list<map>
  mapList:
    - name: mm
      age: 21
    - name: ll
      age: 22

config文件:

/**
 * Copyright (C) 2006-2019 Tuniu All rights reserved
 */
package com.zqm.service;

import com.zqm.config.YamFactory;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

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

/**
 * ConfigurationProperties 注入一个类,对象 --支持宽松绑定
 * 1.5之前还有location属性,指定文件 代替方案@PropertySource
 * prefix前缀定义了哪些外部属性将绑定到类的字段上
 * ignoreInvalidFields 设置为true 绑定失败程序不会报错
 * 根据 Spring Boot 宽松的绑定规则,类的属性名称必须与外部属性的名称匹配
 * 我们可以简单地用一个值初始化一个字段来定义一个默认值
 * 类本身可以是包私有的
 * 类的字段必须有公共 setter 方法
 * <p>
 * <p>
 * Value("${zk.register.merinfo}") 注入地址等简单方式
 *
 * @author zhaqianming
 * <p>
 * Date: 2019-11-05
 */

@Component
@PropertySource(value = "classpath:aalist.yml",factory = YamFactory.class)
@ConfigurationProperties(prefix = "aalist")
@Data
public class YamlTestAaList {
    private String name;
    private List<String> myList;
    private Integer [] arrays;
    private Map<String,String> valueMap;
    private List<Map<String,String>> mapList;
    private Map<Integer,Integer> moduleCategoryMap;
}

附录2springboot读取properties文件:

list.properties:

#map 第一种形式
data.person.name=zam
data.person.sex=man
data.person.age=28
data.person.hight=170
#map 第二种形式
data.student[name]=zqm
data.student[age]=18
data.student[no]=004
#list 第一种方式
data.list[0]=list1
data.list[1]=list2
data.list[2]=list3
#list 第二种方式
data.newList=list4,list5,list5

读取配置代码:

package com.zqm.config;

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

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

/**
 * @describe:
 * @author:zqm
 */
@PropertySource(value = "classpath:list.properties")
@ConfigurationProperties(prefix = "data")
@Component
@Data
public class ListProperties {
    private Map<String,String> student;
    private Map<String,String> person;
    private List<String> list;
    private List<String> newList;

}

debug启动的结果如下:

springboot获取自定义yml的值 springboot读取自定义yml配置文件_spring_03