@Value和@ConfigurationProperties两个注解都可以从配置文件获取值并设置到属性中,用法上有区别。
@Value适用一些比较简单的情形,用得比较普遍;而@ConfigurationProperties则可适用一些@Value无法处理更复杂的情形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| myapp: simple: name: ABC count: 15 countries: CN,US,UK complex: list: - id: k1 value: hello - id: k2 value: nihao - id: k3 value: konichiha nested: name: John address: province: jiangsu city: nanjing
|
例如上面的配置myapp.simple下的属性都可以用@value获取到,甚至myapp.simple.countries也可以被设置到String[]类型的属性上,但是下面的myapp.complex.list设置的配置,@Value就无法把它转成一个List<Map<String, Object>>类型的属性了,而@ConfigurationProperties可以。甚至myapp.complex.nested还可以被@ConfigurationProperties付值到带有两个属性(province, city)的子类中(参照下面的@ NestedConfigurationProperty注解)
@Value
可处理的类型
只可处理String、数值等简单类型,和简单的数组类型,不能处理map、List等复杂类型
位置
直接写在需要从配置文件读取值的成员变量上即可。
例如:
1 2 3 4 5
| @Service public class XxxxService{ @Value("${xxx.yyy}") private String xxxYyy; }
|
参数
只有一个字符型参数value,用于标记配置文件中的key
参数名称 |
类型 |
默认值 |
说明 |
value |
String |
|
从配置文件中哪一项读取值,支持Spring EL |
@ConfigurationProperties
可处理的类型
除了基本类型外,List、Map、 数组, 自定义POJO …
用法
@ConfigurationProperties注解需要写到类上,为该类所有有setter方法的属性从配置文件中读取并付值。@ConfigurationProperties 只能在类上使用,不能用在属性上。
如果类里面的某个属性是另外一个POJO,则在该属性上增加注解 @NestedConfigurationProperty , 这样就可嵌套解析。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @ConfigurationProperties public class xxxYyy{ private String name; @NestedConfigurationProperty Address address;
public void setName(String name){ this.name = name; } public void setAddress(Address address){ this.address = address; } }
public class Address{ private String province; private String city; }
|
参数
参数名称 |
类型 |
默认值 |
说明 |
ignoreInvalidFields |
boolean |
false |
java中被绑定的属性类型与配置文件中设置的值类型不同时是否忽略 |
ignoreUnknownFields |
boolean |
true |
Flag to indicate that when binding to this object invalid fields should be ignored |
prefix |
String |
|
The name prefix of the properties that are valid to bind to this object. |
value |
String |
|
同prefix,简写,支持Spring EL |
前置条件
1、需要增加依赖
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
|
2、需要先开始使用配置属性的功能(不开启不出错,但不会读取配置并设置到类上)
1
| @EnableConfigurationProperties
|
@EnableConfigurationProperties需要写在Spring Boot的启动类或配置类上。
从其他配置文件中读取
如果信息配置在了自定义的配置文件中(不是applicaiton.yml),则可以使用@PropertySource注解来告诉spring从哪个文件读取配置信息,例如:
1
| @PropertySource("classpath:configprops.properties")
|
@PropertySource 注解默认只能解析 properties 文件,如果是yml文件,需要自定义一个解析器
如果需要从其他yml文件读取配置,可以利用 @PropertySource 的 factory 属性,先写一个解析yml 文件的类,这很简单,因为spring中已经包含了解析yml格式的解析器,我们只需要包装一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.EncodedResource; import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException; import java.util.Properties;
public class YamlPropertySourceFactory implements PropertySourceFactory { private static final Logger logger = LoggerFactory.getLogger(YamlPropertySourceFactory.class);
@Override public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(encodedResource.getResource()); Properties properties = factory.getObject(); logger.trace( "read from {}, exists:{}", encodedResource.getResource().getFile().getAbsoluteFile(), encodedResource.getResource().exists()); return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties); } }
|
之后在使用 @PropertySource 注解时增加 factory 属性
1
| @PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:yamlfile.yml")
|