在application.yml中增加
#只能用@Value的写法,数组和集合默认使用‘,’拆分数组
keyfield:
name: valueType
list: 1,2,3
map: "{key1: 10434, key2: 10037}"
#只能用@Value的写法,数组和集集合使用‘-’拆分数组
keyfieldtwo:
name: valueType
list: 1-2-3
# 这种方式只能用@ConfigurationProperties加载
#xxx.xxx[0] 也只能用@ConfigurationProperties
#xxx.xxx[1]
keyfieldproperties:
name: valueType
list:
- 1
- 2
- 3
# maps: { "key1": "value1", "key2": "value2" }
#或者
maps:
key1: "value1"
key2: "value2"
listmap:
- key1: 'value1'
name: 'name1'
- key2: 'value2'
name: 'name2'
方式1:@Value读取
@SpringBootTest
@RunWith(SpringRunner.class)
public class HelloValueTest {
@Value("${keyfield.name}")
private String keyfield_Name;
//@Value默认使用‘,’分割集合;
//这里报错, @Value("${keyfieldproperties.list}")不支持这种方式集合
@Value("${keyfield.list}")
public List<Integer> keyfield_List;
//@Value加载Map,必须使用,@Value("#{${keyfield.map}}")
@Value("#{${keyfield.map}}")
public Map<String,String> keyfield_Map;
//@Value使用‘-’分割集合
@Value("#{'${keyfieldtwo.list}'.split('-')}")
public List<Integer> keyfieldtwo_List;
@Value("硬编码")
private String name_Two;
@Test
public void valueTest() {
System.out.println(keyfield_Name);
System.out.println(keyfield_List);
System.out.println(keyfield_Map);
System.out.println(keyfieldtwo_List);
System.out.println(name_Two);
}
}
1.2 @Value("#{}")和@Value("${}") 区别:
@Value("#{}"):是使用SpEl表达式,,可以表示常量的值,或者获取bean中的属性。
比如@Value("#{'${hellotwo.remarklist}'.split('-')}")
@Value("${}"):从配置文件中直接读取值。
@Value(""):表示硬编码的字符串。
方式2:@ConfigurationProperties
@ConfigurationProperties 将配置直接装换为实体类,无需要定义配置。
@Component
@ConfigurationProperties(prefix = "keyfieldproperties")
@Data
public class KeyFieldProperties {
private String name;
private List<String> list;
private Map<String,String> maps;
private List<Map<String,String>> listMap;
}
2.1 @value和@ConfigurationPropertie区别:
@value支持Spel表达式,而ConfigurationProperties不支持。
@ConfigurationProperties:支持松绑语法(比如remarklist可以命名成remarkList)
@ConfigurationProperties | @value | |
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定 | 支持 | 不支持 |
SpEl | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
@EnableConfigurationProperties注解的作用是:使 @ConfigurationProperties 注解的类生效。
方式3:@PropertySource读取指定名称文件
新建myext.properties配置文件
keyfieldpropertiesext.name=valueType
keyfieldpropertiesext.list[0]=1
keyfieldpropertiesext.list[1]=2
keyfieldpropertiesext.list[2]=3
keyfieldpropertiesext.maps.key1=value1
keyfieldpropertiesext.maps.key2=value2
keyfieldpropertiesext.listmap[0].key1=value1
keyfieldpropertiesext.listmap[0].name=name
keyfieldpropertiesext.listmap[1].key2=value2
keyfieldpropertiesext.listmap[1].name=name2
keyfieldpropertiesext.maplist.root1[0]=root1_1
keyfieldpropertiesext.maplist.root1[1]=root1_2
keyfieldpropertiesext.maplist.root2[0]=root2_1
keyfieldpropertiesext.maplist.root2[1]=root2_2
由于前两种方式只能加载默认的属性文件application.properties所以不够灵活。
使用@PropertySource+@Value注解读取方式
或@PropertySource+@ConfigurationProperties注解读取方式
@Component
@PropertySource("classpath:myext.properties")
@ConfigurationProperties(prefix = "keyfieldpropertiesext")
@Data
public class KeyFieldExtProperties {
private String name;
private List<String> list;
private Map<String, String> maps;
private List<Map<String, String>> listMap;
private Map<String, List<String>> mapList;
}
@PropertySource默认不支持yml或者yaml的解析。
@PropertySource 的注解中,有一个factory属性,可指定一个自定义的PropertySourceFactory接口实现,用于解析指定的文件。默认的实现是DefaultPropertySourceFactory,发现默认使用了PropertiesLoaderUtils.loadProperties进行文件解析,所以默认使用Properties进行解析的。
新建一个CustomizePropertySourceFactory并且继承DefaultPropertySourceFactory
public class CustomizePropertySourceFactory 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();
}
}
@Component
//@PropertySource("classpath:myext.properties")
//PropertySource默认不支持yml或者yaml的解析
@PropertySource(value = "classpath:myext.yml", factory = CustomizePropertySourceFactory.class)
@ConfigurationProperties(prefix = "keyfieldpropertiesext")
@Data
public class KeyFieldExtProperties {
private String name;
private List<String> list;
private Map<String, String> maps;
private List<Map<String, String>> listMap;
private Map<String, List<String>> mapList;
}
方式4:Environment读取方式
@Autowired
private Environment env;
// 获取参数
env.getProperty(key);