搞了一阵子C++,以前感觉C++很牛,现在怎么觉得这东西这么落后了,很多理念完全跟不上时代,关键兼容性让人抓狂了。。。只能说一切为了效率。。。
来看看spring-boot,完全是魔术啊,觉得spring的脑洞真大啊,来说一下今天的主角@ConfigurationProperties。
概述
我们知道,从spring-boot开始,已经支持yml文件形式的配置,@ConfigurationProperties的大致作用就是通过它可以把properties或者yml配置直接转成对象。
配置文件转成对象
Relaxed binding
用@ConfigurationProperties是支持“松绑定”的,我们不必每个字都和配置中的key一致。官网给出了两个例子,e.g.
context-path
binds to contextPath
和e.g. PORT
binds to port
集合的处理
如果在配置中需要配置集合的话,我们需要使用“-”符号
比如:
poolConfig:
- maxIdle: 8
- minIdle: 0
- maxActive: 8
- maxWait: -1
元数据(Meta-data)
@ConfigurationProperties还支持spring元数据,可以在resource下建立META-INF文件夹,然后建立文件additional-spring-configuration-metadata.json。里面的数据格式必须满足spring的元数据格式http://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/htmlsingle/#configuration-metadata
接下来我们来看个例子
yml配置如下:
spring:
redis:
dbIndex: 0
hostName: 192.168.58.133
password: nmamtf
port: 6379
timeout: 0
poolConfig:
- maxIdle: 8
- minIdle: 0
- maxActive: 8
- maxWait: -1
定义被转换的对象
@Component
@ConfigurationProperties(prefix="spring.redis")
public class RedisProps {
private int dbIndex;
@NotNull
private String hostname;
private String password;
@NotNull
private int port;
private long timeout;
private List<Map<String,String>> poolConfig;
public int getDbIndex() {
return dbIndex;
}
public void setDbIndex(int dbIndex) {
this.dbIndex = dbIndex;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public long getTimeout() {
return timeout;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
public List<Map<String, String>> getPoolConfig() {
return poolConfig;
}
public void setPoolConfig(List<Map<String, String>> poolConfig) {
this.poolConfig = poolConfig;
}
}
这样该对象的成员变量会被自动赋值,可以在其他地方进行注入
直接注入配置到java config中
如果你嫌上面还麻烦,那么接下来的这个功能绝对让你惊艳。
该功能在官方文档是没有提到的,我们可以把@ConfigurationProperties和@Bean和在一起使用。
举个例子,我们需要用@Bean配置一个Config对象,Config对象有a,b,c成员变量需要配置,那么我们只要在yml或properties中定义了a=1,b=2,c=3,然后通过@ConfigurationProperties就能把值注入进Config对象中。这是魔术吗?
下面我用实际的代码举个例子
yml配置文件修改如下
server:
port: 8080
spring:
redis:
dbIndex: 0
hostName: 192.168.58.133
password: nmamtf
port: 6379
timeout: 0
poolConfig:
maxIdle: 8
minIdle: 0
maxActive: 8
maxWait: -1
接着我们用@ConfigurationProperties来配置redis
@Configuration
@EnableAutoConfiguration
public class RedisConfig {
@Bean
@ConfigurationProperties(prefix="spring.redis.poolConfig")
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisConnectionFactory getConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setUsePool(true);
JedisPoolConfig config = getRedisConfig();
factory.setPoolConfig(config);
return factory;
}
@Bean
public RedisTemplate<?, ?> getRedisTemplate(){
RedisTemplate<?,?> template = new StringRedisTemplate(getConnectionFactory());
return template;
}
}
注意,其中JedisConnectionFactory中包含dbIndex,hostName,password,port,timeout,poolConfig几个成员变量。JedisPoolConfig包含maxIdle,minIdle,maxActive,maxWait几个成员变量。
@ConfigurationProperties和@Value比较
它们两个都能把配置文件的值直接注入到代码,那么它们的区别是什么呢,怎么选择呢,直接拿官方的表格一下就清楚了
Feature | @ConfigurationProperties | @Value |
---|---|---|
Yes | No | |
Yes | No | |
| No | Yes |